İçeriğe atla
HexaTransfer
Bloga dön
Teknik incelemeler

Çevrimdışı Transfer İçin Service Worker Dosya Önbelleği

Çevrimdışı dosya transferi yeteneklerine imkan tanımak için Service Worker kullanın. Önbellek stratejileri, arka plan senkronizasyonu ve PWA desenleri.

Service Worker'lar, ağ kesildiğinde dosya transfer uygulamasının çalışmaya devam etmesini sağlar: HTML kabuğunu ve JS'i Cache API ile önbelleğe alın, başarısız yüklemeleri Background Sync API ile sıraya koyun, kısmi parçaları IndexedDB'de depolayın ve bağlantı geri geldiğinde her şeyi yeniden çalıştırın. Worker, kendi olay döngüsüne sahip ayrı bir iş parçacığında çalışır, kapsamı dahilindeki fetch olaylarını yakalar ve sekme kapamalarından sonra da devam eder. Yükleme araçları için doğru tarif şudur: uygulama kabuğu için stale-while-revalidate stratejisi, uçuştaki transferler için IndexedDB destekli parça sıralaması ve başarılı olana kadar yüklemeleri 15 dakikada bir yeniden deneyen periyodik Background Sync kaydı.

Service Worker'ların Transfer Uygulamalarına Gerçekte Katkısı

Büyük kazanç, navigator.serviceWorker'ın sekme yeniden yüklemelerinden, çevrimdışı dönemlerden ve hatta telefon uyku modundan sağ çıkmasıdır. Bir kullanıcı kararsız tren Wi-Fi'sında 2 GB'lık yükleme başlattığında, zaten başarılı olan parçaların başarılı kalmasını, uçuştakilerin yeniden bağlanmada yeniden denenmesini ve tarayıcı sekmeyi hafıza geri kazanmak için sonlandırsa bile tüm durumun kurtarılabilir olmasını istiyorsunuz. Belirli bir sekmeden bağımsız çalışan bir Service Worker, bunların tamamını mümkün kılan parçadır.

API size üç yapı taşı sunar: URL'ye göre yanıtları depolamak için Cache, yapılandırılmış veriler için IndexedDB (parça kuyrukları, oturum durumu) ve cihaz çevrimiçi olduğunda tetiklenecek yeniden denemeleri planlamak için SyncManager.

Worker'ı Kaydetme ve Sürümleme

Uygulama yüklenirken bir kez kaydedin ve güncellemeleri açıkça yönetin:

if ('serviceWorker' in navigator) {
  navigator.serviceWorker.register('/sw.js', { scope: '/' })
    .then((reg) => reg.addEventListener('updatefound', () => {
      const sw = reg.installing;
      sw.addEventListener('statechange', () => {
        if (sw.state === 'installed' && navigator.serviceWorker.controller) {
          // yeni sürüm hazır, kullanıcıya yenileme isteyin
        }
      });
    }));
}

Yeni bir dağıtımın eski JavaScript'i geride bırakmadan eski varlıkları geçersiz kılması için önbellek anahtarlarınızı sürümlendirin (transfer-v7). Klasik hata: index.html sonsuza kadar önbelleğe alınır, kullanıcılar hiçbir zaman güncellemeyi almaz ve haftalarca hata ayıklama yaparsınız. Önbellekleri derleme hash'lerine sabitleyin ve activate olayında temizleyin.

Uygulama Kabuğu ve Kullanıcı Verisi İçin Önbellek Stratejileri

Farklı kaynaklar farklı stratejileri hak eder:

  • Uygulama kabuğu (HTML, CSS, JS, ikonlar): ağ geri dönüşlü önbellek-önce. Anlık yükleme, çevrimdışı çalışır.
  • API metadata (/shares/:id): 60 saniyelik TTL ile önbellek geri dönüşlü ağ-önce. Çevrimiçiyken güncel, değilken kullanılabilir.
  • Dosya baytları: asla önbelleğe almayın. Dosyalar çoğunlukla çok gigabaytlıktır ve Cache API'nin kaynak kotaları vardır (genellikle boş diskin %60'ı).
  • CDN'lerden fontlar: stale-while-revalidate. Hızlı ve otomatik yenileniyor.

fetch işleyicisinde:

self.addEventListener('fetch', (e) => {
  const url = new URL(e.request.url);
  if (url.pathname.startsWith('/assets/')) {
    e.respondWith(cacheFirst(e.request, 'shell-v7'));
  } else if (url.pathname.startsWith('/api/shares/')) {
    e.respondWith(networkFirst(e.request, 'api-v1', 60));
  }
});

İkili dosya yüklemeleri için istekleri asla yakalamayın — e.request.method === 'PUT' kontrol ederek ve erkenden dönerek onları yönlendirin. Gigabaytlık PUT'ları worker üzerinden proxy'lemek bir bellek felaketidir.

Background Sync İle Başarısız Yüklemeleri Sıraya Alma

SyncManager, dayanıklı yüklemelerin anahtarıdır. Bir parça PUT başarısız olduğunda IndexedDB'ye kaydedin ve bir senkronizasyon kaydedin:

// sayfa kodunda
const reg = await navigator.serviceWorker.ready;
await reg.sync.register('flush-uploads');
// sw.js içinde
self.addEventListener('sync', (event) => {
  if (event.tag === 'flush-uploads') {
    event.waitUntil(flushPendingUploads());
  }
});

Tarayıcı, ~24 saate kadar üstel geri çekilmeyle ağ geri geldiğinde sync olayını tetikler. Chrome ve Edge destekler; Safari 17.5'te "Background Fetch" bayrağı altında bir alt kümeyi kullanıma açtı ancak kullanıcı izni gerektirir. Safari için, bir sonraki görünür sayfa açılışında visibilitychange aracılığıyla yeniden denemeye geri dönün.

Background Fetch API, büyük dosya işlemleri için ayrı bir araçtır — sekmeyi kapattıktan sonra bile kullanıcıların ilerlemeyi izleyebilmesi için tarayıcı kullanıcı arayüzünde kalıcı bir bildirim gösterir. 500 MB'ın üzerindeki yüklemeler için kullanılmaya değer.

Kısmi Yüklemeleri IndexedDB'de Depolama

IndexedDB sizin dayanıklı çalışma alanınızdır. Küçük bir veritabanını bir kez açın, ardından oturum metadata'sını ve parça offsetlerini saklayın:

const db = await openDB('transfers', 1, {
  upgrade(db) {
    db.createObjectStore('sessions', { keyPath: 'id' });
    db.createObjectStore('chunks', { keyPath: ['sessionId', 'index'] });
  }
});
await db.put('sessions', {
  id, fileName, fileSize, fileFingerprint, createdAt: Date.now(),
  completedIndexes: [], partUrls
});

Ham parça baytları depolamayın — File tanıtıcısından gelirler; IndexedDB, yeniden yüklemeler arasında geçerli kalan yapısal klon referansı olarak bunları kalıcı hale getirebilir. Tanıtıcıyı depolamak, veritabanında 2 GB'lık baytları kopyalamaktan kaçınır.

Kaynak depolamasının sınırları vardır: masaüstü Chrome'da boş diskin yaklaşık %60'ı, tahliye baskısı devreye girmeden önce iOS Safari'de kaynak başına 1 GB. Tarayıcıların otomatik olarak tahliyeden kaçındığı "kalıcı" kovayı almak için navigator.storage.persist() isteyin.

Çevrimdışı ve Çevrimiçi Geçişlerin Yönetimi

Hem sayfada hem service worker'da online ve offline olaylarını dinleyin:

// sayfa
window.addEventListener('online', () => {
  ui.showBanner('Tekrar çevrimiçi — yüklemeler devam ediyor');
  navigator.serviceWorker.controller?.postMessage({ type: 'resume' });
});
window.addEventListener('offline', () => {
  ui.showBanner('Çevrimdışı — yüklemeler duraklatıldı');
});

navigator.onLine, kurumsal captive portal'larda ünlü biçimde güvenilmezdir — cihazın yerel ağ bağlantısı ancak interneti yokken true bildirir. Güvenilir algılama için, 3 saniyelik zaman aşımıyla küçük bir fetch('/ping', { cache: 'no-store' }) yapın.

Uygun bir PWA Haline Getirme

display: standalone, ikon seti ve start_url: / ile bir manifest.json gönderin. iOS için apple-touch-icon bağlantıları ekleyin. İşletim sisteminin uygulamanızı belirli uzantılarla ilişkilendirebilmesi için dosya işlemeyi bildirin:

{
  "name": "Hex Transfer",
  "file_handlers": [{
    "action": "/share-target",
    "accept": { "application/*": [".pdf", ".zip", ".docx"] }
  }]
}

Web Share Target ile birleştirildiğinde bu, kullanıcıların işletim sistemi paylaşım sayfasından doğrudan uygulamanıza dosya paylaşmasına olanak tanır. Chrome Android ve masaüstü Chromium'da PWA, bildirdiğiniz dosya türleri için varsayılan işleyici olarak kaydedilebilir. Bu, bir tarayıcı sayfasını yerel bir yükleme aracı gibi davranan bir uygulamaya dönüştürür.

Çevrimdışı Senaryoyu Test Etme

Otomatik çevrimdışı testler güvenilmez olduğundan, elle test edilecek üç senaryo:

  1. Hızlı Wi-Fi'da 500 MB'lık yükleme başlatın, %30'da uçak moduna geçin, 30 saniye bekleyin, Wi-Fi'ı açın. Yükleme, kullanıcı işlemi olmadan durduğu yerden devam etmelidir.
  2. Yükleme başlatın, %60'da sekmeyi kapatın, 2 dakika bekleyin, yeniden açın. Oturumu devam ettirmeyi teklif edin.
  3. Mobilde yükleme başlatın, 5 dakika ekranı kilitleyin. Kilit açıldığında arka plan senkronizasyonu tetiklenmeli ve transferi tamamlamalıdır.

Chrome DevTools'un "Offline" onay kutusu ve Application > Service Workers > Update on reload vazgeçilmezdir. Network panelinin "Throttling" profilleri hata kullanıcı arayüzünüzün nasıl davrandığını görmek için Fast 3G ve Slow 3G simüle etmenizi sağlar.

HexaTransfer'in web uygulaması, uygulama kabuğu önbelleğe alma için Service Worker ve uçuştaki oturum durumu için IndexedDB kullanır; bu sayede yeniden yüklemeler ve kısa çevrimdışı dönemler yükleme ilerlemesini kaybetmez. hexatransfer.com'da deneyin — ücretsiz, hesap gerekmez, maksimum 10 GB.

Bilinmeye Değer Tuzaklar

Service Worker'ların yeni başlayanları tuzağa düşüren küçük bir sorular yığını vardır: yalnızca HTTPS üzerinde çalışırlar (localhost hariç), önbellek kotaları tarayıcılar arasında büyük farklılıklar gösterir, iOS Safari Background Sync için worker'ları güvenilir biçimde uyandırmaz, DevTools eski worker'ları agresif şekilde önbelleğe alabilir (geliştirirken her zaman "Bypass for network"ü tıklayın) ve importScripts yükleme sırasında eşzamanlı çalışır, bu yüzden yavaş üçüncü taraf betiklerini asla oraya çekmeyin. Worker'ın etkinleştiğini, istemcileri talep ettiğini ve çevrimdışı sayfayı sunduğunu kontrol eden küçük bir entegrasyon testi yazın — bu tek test, üretimde karşılaşacağınız gerilemelerin %80'ini yakalar.

Uçtan uca şifreleme ile büyük dosyaları güvenle gönderin

Uçtan uca şifreleme ile 10 GB'a kadar dosya ücretsiz aktarın. Hesap gerekmez. Dosyalarınız yüklenmeden önce tarayıcınızda şifrelenir — başka kimse okuyamaz.

Dosya gönder