Mobil Micro Frontend'lerde WebView İletişim Pattern'leri
React Native ve WebView'lar arasında güvenli ve verimli iletişim kurma. Postmessage, bridge pattern'leri ve production deneyimleri.
Mobil micro frontend mimarimizi devreye aldıktan üç ay sonra bir duvara çarptık. WebView-native iletişimimiz debugging kâbusu haline geliyordu. Mesajlar kayboluyordu, platformlar arası tipler eşleşmiyordu, ve production'da WebView'ların içinde neler olduğunu takip edemiyorduk. Bu yazıda PostMessage tabanlı bridge pattern'imizi, type-safe iletişim katmanını ve production'dan öğrendiklerimizi paylaşıyorum.
Zorluklar kritik bir ürün lansmanı sırasında ortaya çıktı. Native kimlik doğrulama ve WebView checkout'u arasında bölünmüş ödeme akışımız, Android kullanıcılarının 15%'i için başarısız olmaya başladı. WebView ready-state'i doğrulamadan mesaj göndermek yaygın bir tuzak; ready-state polling veya event listener ile çözülebilir. Ana sebep? Yalnızca daha yavaş JavaScript motorlarına sahip cihazlarda görülen mesaj geçiş sistemimizde bir race condition. WebView hazır olmadan gönderilen mesajlar kayboluyordu. İşte iletişim katmanımızı sıfırdan nasıl yeniden inşa ettiğimiz ve production WebView iletişim sistemimizden neler öğrendiğimiz. TypeScript ile type-safe bridge'ler ve ready-state polling pattern'i bu sorunları çözdü—aşağıda uygulanabilir kod örnekleri bulacaksın. Mesaj sıralaması ve timeout mekanizmaları özellikle önemli; yavaş cihazlarda WebView inject edilmeden önce gönderilen komutlar sessizce kaybolur.
Mobil Micro Frontend Serisi
Bu, mobil micro frontend serimizin 2. bölümü. PostMessage, bridge pattern'leri ve production deneyimleriyle devam ediyoruz:
- 1. Bölüm: Mimari temeller ve WebView entegrasyon pattern'leri
- 2. Bölüm (Buradasınız): WebView iletişim pattern'leri ve servis entegrasyonu
- 3. Bölüm: Multi-channel mimari ve production optimizasyonu
1. Bölümü okumadınız mı? Mimari temeller için oradan başlayın. Production için hazır mısınız? Optimizasyon stratejileri için 3. Bölüm'e geçin.
Alternatif İletişim Yaklaşımları
WebView iletişim çözümümüze dalmadan önce, değerlendirdiğimiz alternatif yaklaşımları ve neden mevcut sistemimizi seçtiğimizi paylaşayım. PostMessage, Re.Pack Module Federation ve custom URL scheme'leri inceledik; her birinin trade-off'ları vardı.
Seçenek 1: Re.Pack Module Federation İletişimi
Re.Pack, Module Federation aracılığıyla farklı bir iletişim modeli sunar. Mesaj geçirme yerine, native ve web bağlamları arasında doğrudan modül paylaşımına olanak tanır.
Denediğimiz şey:
Neden seçmedik:
- Karmaşıklık: Tüm ekiplerin aynı anda Module Federation'ı benimsemeleri gerekiyordu; mevcut postMessage tabanlı sistemle kademeli geçiş zordu.
- Type safety: Paylaşılan modüllerin ayrı bir package'da olması gerekiyordu; bu da build pipeline'ını karmaşıklaştırırdı.
- Versioning: Modül versiyon çakışmaları debug etmesi zordu
- Performans: İlk bundle boyutu önemli ölçüde artıyordu
- Debugging: Stack trace'ler birden fazla context'e yayılıyordu
Re.Pack Module Federation'ı ne zaman kullanmalı:
- Gerçek bir super app inşa ediyorsanız
- Tüm ekipler paylaşılan modüller üzerinde koordine olabiliyorsa
- Context'ler arası doğrudan fonksiyon çağrılarına ihtiyacınız varsa
- Performans overhead'i kabul edilebilirse
Seçenek 2: Rspack Module Federation
İletişim için Rspack'in Module Federation'ı ile de deneme yaptık:
Neden seçmedik:
- React Native uyumluluğu: Rspack'in native React Native desteği yok
- Ekosistem olgunluğu: Daha az debugging aracı ve örnek
- Ekip adaptasyonu: Önemli ölçüde yeniden eğitim gerektirecekti
- Production kararlılığı: Zamanımız için çok yeni
Rspack Module Federation'ı ne zaman kullanmalı:
- Yalnızca web micro frontend'leri inşa ediyorsanız
- Build performansı kritikse
- Erken benimseyen olma lüksünüz varsa
- Ekipleriniz Rust tabanlı araçlarda rahatsa
Seçenek 3: Web Workers + SharedArrayBuffer
Yüksek performanslı iletişim için, Web Workers ile SharedArrayBuffer'ı değerlendirdik:
Neden seçmedik:
- Browser desteği: SharedArrayBuffer spesifik header'lar gerektiriyor
- Karmaşıklık: Implement etmesi ve debug etmesi çok daha karmaşık
- Güvenlik: Dikkatli bellek yönetimi gerektiriyor
- Platform farklılıkları: iOS WebView'da farklı SharedArrayBuffer davranışı
SharedArrayBuffer'ı ne zaman kullanmalı:
- Aşırı yüksek performanslı iletişime ihtiyacınız varsa
- Yalnızca modern browser'ları hedefliyorsanız
- Karmaşıklığı kaldırabiliyorsanız
- Performans basitlikten daha önemliyse
Seçenek 4: WebSocket Bridge
Real-time iletişim için WebSocket'leri değerlendirdik:
Neden seçmedik:
- Network bağımlılığı: Network bağlantısı gerektiriyor
- Latency: Ek network hop'u
- Karmaşıklık: WebSocket lifecycle'ını yönetmek gerekiyor
- Güvenlik: Ek saldırı yüzeyi
WebSocket bridge'i ne zaman kullanmalı:
- Real-time iletişime ihtiyacınız varsa
- Network latency kabul edilebilirse
- Dağıtık sistem inşa ediyorsanız
- Bi-directional streaming'e ihtiyacınız varsa
İletişim Zorluğu
WebView iletişimi başta basit görünür. Web tarafında postMessage, native tarafında onMessage var. Neyin yanlış gidebileceği?
Her şey, anlaşılan:
- Mesajlar string, bu yüzden type safety kaybediyorsunuz
- Built-in request/response pattern'i yok
- Delivery garantisi veya acknowledgment yok
- iOS ve Android arasında farklı davranış
- Timeout veya retry'ları handle etme yolu yok
- Büyük payload'larla performans degradasyonu
Sağlam Mesaj Protokolü İnşa Etmek
Birkaç iterasyondan sonra, bu sorunları çözen bir protokol geliştirdik:
Native Taraf Implementasyonu
React Native tarafındaki production bridge implementasyonumuz:
Web Taraf Implementasyonu
Web tarafının mesajları handle etmesi ve benzer API sağlaması gerekiyor:
Type-Safe İletişim
En büyük kazanımlarımızdan biri bridge üzerinde type safety elde etmekti. İşte nasıl yaptığımız:
Kullanım tamamen type-safe hale geliyor:
Servis Entegrasyon Pattern'leri
Bridge üzerinden çeşitli servisleri nasıl entegre ettiğimiz:
Authentication Service
Native Özellik Erişimi
Native özellikleri WebView'lara nasıl açtığımız:
Performans Optimizasyonu
Production'a deploy ettikten sonra, birkaç performans darboğazı keşfettik:
Büyük Payload Handling
PostMessage üzerinden büyük payload'lar (resimler, dökümanlar) göndermek yavaştı ve UI'yı dondurabıliyordu. Çözümümüz chunking'di:
Mesaj Batching
Analytics gibi yüksek frekanslı event'ler için batching implement ettik:
Debugging ve İzleme
Production debugging başlangıçta kâbustu. İşte nasıl yönetilebilir hale getirdik:
Mesaj Logging ve Replay
Remote Debugging Kurulumu
Production debugging için remote debugging yeteneği implement ettik:
Gerçek Dünya Zorlukları ve Çözümleri
Race Condition Bug'ı
Bahsettiğim ödeme akışı bug'ını hatırlıyor musunuz? İşte neler oluyordu:
- WebView auth token talep ediyor
- Native app token refresh başlatıyor
- WebView yanıt beklerken timeout oluyor
- Native app refresh'i tamamlıyor ve yanıt gönderiyor
- WebView çoktan devam etmiş, yanıt yoksayılıyor
Düzeltme, uygun request cancellation implement etmeyi gerektirdi:
Platform-Spesifik Quirk'ler
iOS ve Android WebView'lar ince yollarla farklı davranıyor:
Performans Sonuçları
Bu pattern'ler metriklerimizde önemli iyileşmelere yol açtı:
Mesaj Performansı
- Ortalama yanıt süresi: 45ms (180ms'den düştü)
-
- yüzdelik: 200ms (2s'den düştü)
- Başarısız mesajlar: 0.01% (2.3%'ten düştü)
Bellek Kullanımı
- Bridge overhead'i: WebView başına ~5MB
- Mesaj kuyruğu zirvesi: 15MB (batching ile)
- 24 saatlik stress test sonrası memory leak yok
Batarya Etkisi
- 5% batarya tüketimi azalması
- Esas olarak batching ve mesaj frekansını azaltmaktan
Önemli Çıkarımlar
-
Başarısızlık için Tasarla: Her mesaj başarısız olabilir. İlk günden retry ve timeout handling inşa et.
-
Type Safety Kritik: Bridge üzerinde TypeScript tiplerindeki yatırım, debugging süresini 10x azaltarak geri döndü.
-
Performans Batching Gerektiriyor: Bireysel mesajlar pahalı. Mümkün olduğunda batch'le.
-
Platform Farklılıkları Önemli: Hem iOS hem Android'de, özellikle eski cihazlarda iyice test et.
-
Debugging Araçları Hayati: Göremediğini düzeltemezsin. Kapsamlı logging'i erken inşa et.
-
Alternatif Yaklaşımların Trade-off'ları Var: Her iletişim metodunun güçlü yanları var. Spesifik ihtiyaçlarınıza göre seçin.
Sırada Ne Var?
3. Bölüm'te şunları keşfedeceğiz:
- Multi-channel rendering (aynı micro frontend app, web ve desktop'ta)
- Production performans optimizasyon teknikleri
- Offline mod ve sync handling
- Güvenlik değerlendirmeleri ve sandboxing
İletişim katmanı mobil micro frontend'lerin kalbidir. Doğru yaparsanız, diğer her şey yönetilebilir hale gelir. Yanlış yaparsanız, bizim gibi sabah 3'te race condition'ları debug edersiniz.
Bir dahaki sefere, bu mimarinin birden fazla platformda nasıl ölçeklendiğini ve production'da bulduğumuz şaşırtıcı optimizasyonları inceleyeceğiz.
React Native ile Mobil Micro Frontend'ler
React Native, Expo ve WebView'lar kullanarak mobil micro frontend'ler oluşturma üzerine 3 bölümlük kapsamlı seri. Mimari, iletişim pattern'leri ve production optimizasyonu dahil.