Sunum

Progressive Web Apps'in önemli özelliklerinden biri güvenilir olmalarıdır. Öğeleri hızlıca yükleyebilir, kullanıcıları etkileşimde tutabilir ve kötü ağ koşullarında bile anında geri bildirim sağlayabilirler. Bu nasıl mümkün? Hizmet çalışanı fetch etkinliği sayesinde.

Browser Support

  • Chrome: 40.
  • Edge: 17.
  • Firefox: 44.
  • Safari: 11.1.

Source

fetch etkinliği, hem aynı kaynaktan hem de farklı kaynaklardan gelen istekler için PWA'nın servis çalışanının kapsamında yaptığı her ağ isteğini durdurmamıza olanak tanır. Gezinme ve öğe isteklerine ek olarak, yüklü bir hizmet çalışanından getirme, sitenin ilk yüklenmesinden sonraki sayfa ziyaretlerinin ağ çağrıları olmadan oluşturulmasına olanak tanır.

fetch işleyicisi, URL'ler ve HTTP üstbilgileri dahil olmak üzere bir uygulamadan gelen tüm istekleri alır ve bunların nasıl işleneceğine uygulama geliştiricinin karar vermesine olanak tanır.

Hizmet çalışanı, istemci ile ağ arasında yer alır.

Hizmet çalışanınız bir isteği ağa yönlendirebilir, önceden önbelleğe alınmış bir yanıtla yanıt verebilir veya yeni bir yanıt oluşturabilir. Seçim size kalmış. Basit bir örnek verelim:

self.addEventListener("fetch", event => {
    console.log(`URL requested: ${event.request.url}`);
});

İstekleri yanıtlama

Hizmet çalışanınıza bir istek geldiğinde iki seçeneğiniz vardır: İsteği yoksayabilir (bu durumda istek ağa gönderilir) veya yanıtlayabilirsiniz. Kullanıcı çevrimdışıyken bile hizmet işleyicinizden gelen isteklere yanıt vererek, PWA'nıza nelerin ve nasıl döndürüleceğini seçebilirsiniz.

Gelen bir isteği yanıtlamak için fetch etkinlik işleyicisinden event.respondWith() işlevini çağırın. Örneğin:

// fetch event handler in your service worker file
self.addEventListener("fetch", event => {
    const response = .... // a response or a Promise of response
    event.respondWith(response);
});

respondWith() işlevini senkronize olarak çağırmanız ve bir Yanıt nesnesi döndürmeniz gerekir. Ancak getirme olay işleyicisi sona erdikten sonra respondWith()'ü çağıramazsınız (ör. bir eşzamansız çağrıda). Yanıtın tamamını beklemeniz gerekiyorsa respondWith() için bir Promise iletebilirsiniz. Bu Promise, bir Response ile çözülür.

Yanıt oluşturma

Fetch API sayesinde JavaScript kodunuzda HTTP yanıtları oluşturabilirsiniz. Bu yanıtlar, Cache Storage API kullanılarak önbelleğe alınabilir ve bir web sunucusundan geliyormuş gibi döndürülebilir.

Yanıt oluşturmak için yeni bir Response nesnesi oluşturun, gövdesini ve durum ile üstbilgi gibi seçeneklerini ayarlayın:

const simpleResponse = new Response("Body of the HTTP response");

const options = {
   status: 200,
   headers: {
    'Content-type': 'text/html'
   }
};
const htmlResponse = new Response("<b>HTML</b> content", options)

Önbellekten yanıt verme

Bir hizmet çalışanından HTTP yanıtlarını nasıl yayınlayacağınızı bildiğinize göre, öğeleri cihazda depolamak için Önbelleğe Alma Depolama Arayüzü'nü kullanma zamanı geldi.

PWA'dan alınan isteğin önbellekte olup olmadığını kontrol etmek için önbelleğe alma API'sini kullanabilir ve varsa respondWith()'ye bu isteği kullanarak yanıt verebilirsiniz. Bunun için önce önbellekte arama yapmanız gerekir. Üst düzey caches arayüzünde bulunan match() işlevi, kaynağınızdaki veya tek bir açık önbelleğe alma nesnesindeki tüm mağazaları arar.

match() işlevi, bağımsız değişken olarak bir HTTP isteği veya URL alır ve ilgili anahtarla ilişkili yanıtla çözülen bir promise döndürür.

// Global search on all caches in the current origin
caches.match(urlOrRequest).then(response => {
   console.log(response ? response : "It's not in the cache");
});

// Cache-specific search
caches.open("pwa-assets").then(cache => {
  cache.match(urlOrRequest).then(response => {
    console.log(response ? response : "It's not in the cache");
  });
});

Önbelleğe alma stratejileri

Dosyaları yalnızca tarayıcı önbelleğinden sunmak her kullanım alanına uygun değildir. Örneğin, kullanıcı veya tarayıcı önbelleği kaldırabilir. Bu nedenle, PWA'nız için öğe yayınlama konusunda kendi stratejilerinizi belirlemeniz gerekir. Tek bir önbelleğe alma stratejisiyle sınırlı değilsiniz. Farklı URL kalıpları için farklı kurallar tanımlayabilirsiniz. Örneğin, minimum kullanıcı arayüzü öğeleri için bir strateji, API çağrıları için başka bir strateji ve resim ve veri URL'leri için üçüncü bir stratejiniz olabilir. Bunu yapmak için ServiceWorkerGlobalScope.onfetch içindeki event.request.url öğesini okuyup normal ifadeler veya URL kalıbı aracılığıyla ayrıştırın. (Bu makalenin yazıldığı sırada URL kalıbı tüm platformlarda desteklenmiyordur.)

En yaygın stratejiler şunlardır:

Önce Önbelleğe Al
Öncelikle önbelleğe alınmış bir yanıt arar ve bulunamazsa ağa geri döner.
Önce Ağ
Önce ağdan yanıt ister ve yanıt döndürülmezse önbellekte yanıt olup olmadığını kontrol eder.
Yeniden Doğrulama Sırasında Eski
Arka planda en son sürümü ister ve öğe bir sonraki kez istendiğinde önbelleğe kaydeder. Bu sırada önbellekten bir yanıt sunar.
Yalnızca ağ
Her zaman ağdan gelen bir yanıtla yanıt verir veya hata verir. Önbelleğe hiçbir zaman başvurulmaz.
Yalnızca Önbellek
Her zaman önbellekten bir yanıtla yanıt verir veya hata verir. Ağa hiçbir zaman danışılmaz. Bu strateji kullanılarak yayınlanacak öğeler, istenmeden önce önbelleğe eklenmelidir.

Önce önbelleğe alma

Hizmet çalışanı bu stratejiyi kullanarak önbellekte eşleşen isteği arar ve önbelleğe alınmışsa ilgili yanıtı döndürür. Aksi takdirde yanıtı ağdan alır (isteğe bağlı olarak, gelecekteki çağrılar için önbelleği günceller). Önbelleğe alınmış yanıt veya ağ yanıtı yoksa istek hatayla sonuçlanır. Öğelerin ağa gitmeden yayınlanması daha hızlı olduğu için bu strateji, yenilik yerine performansa öncelik verir.

Önce Önbelleğe Alma stratejisi

self.addEventListener("fetch", event => {
   event.respondWith(
     caches.match(event.request)
     .then(cachedResponse => {
       // It can update the cache to serve updated content on the next request
         return cachedResponse || fetch(event.request);
     }
   )
  )
});

Ağ önceliklidir

Bu strateji, Önbelleği Önce stratejisinin aynasıdır; isteğin ağdan karşılanıp karşılanamayacağını kontrol eder ve karşılanamazsa önbellekten getirmeyi dener. Önce önbelleği temizleyin. Ağ yanıtı veya önbellek yanıtı yoksa istek hatalı olur. Yanıtın ağdan alınması genellikle önbellekten alınmasından daha yavaştır. Bu strateji, performans yerine güncellenmiş içeriğe öncelik verir.

Ağ öncelikli strateji

self.addEventListener("fetch", event => {
   event.respondWith(
     fetch(event.request)
     .catch(error => {
       return caches.match(event.request) ;
     })
   );
});

Yeniden doğrulama sırasında eski

"Yeniden doğrulama sırasında eski" stratejisi, önbelleğe alınmış bir yanıtı hemen döndürür, ardından ağda güncelleme olup olmadığını kontrol eder ve güncelleme bulunursa önbelleğe alınmış yanıtı değiştirir. Bu strateji her zaman bir ağ isteği gönderir. Çünkü önbelleğe alınmış bir kaynak bulunsa bile güncellenmiş sürümü bir sonraki isteğinde kullanmak için önbellekte bulunanları ağdan alınanlarla güncellemeye çalışır. Bu nedenle bu strateji, önbelleği önce stratejisinin hızlı sunma özelliğinden yararlanmanıza ve önbelleği arka planda güncellemenize olanak tanır.

Yeniden doğrulama sırasında eski strateji

self.addEventListener('fetch', event => {
  event.respondWith(
    caches.match(event.request).then(cachedResponse => {
        const networkFetch = fetch(event.request).then(response => {
          // update the cache with a clone of the network response
          const responseClone = response.clone()
          caches.open(url.searchParams.get('name')).then(cache => {
            cache.put(event.request, responseClone)
          })
          return response
        }).catch(function (reason) {
          console.error('ServiceWorker fetch failed: ', reason)
        })
        // prioritize cached response over network
        return cachedResponse || networkFetch
      }
    )
  )
})

Yalnızca ağ

Yalnızca ağ stratejisi, tarayıcıların hizmet çalışanı veya Önbellek Depolama API'si olmadan nasıl davrandığına benzer. İstekler yalnızca ağdan alınabilen kaynakları döndürür. Bu, genellikle yalnızca internet üzerinden yapılan API istekleri gibi kaynaklar için kullanışlıdır.

Yalnızca ağ stratejisi

Yalnızca önbelleğe alma

Yalnızca önbelleğe alma stratejisi, isteklerin hiçbir zaman ağa gönderilmemesini sağlar. Gelen tüm isteklere önceden doldurulmuş bir önbelleğe alma öğesiyle yanıt verilir. Aşağıdaki kod, yalnızca önbelleğe yanıt vermek için önbelleğe depolama alanının match yöntemiyle birlikte fetch etkinlik işleyicisini kullanır:

self.addEventListener("fetch", event => {
   event.respondWith(caches.match(event.request));
});

Yalnızca önbelleğe alma stratejisi.

Özel stratejiler

Yukarıdakiler yaygın önbelleğe alma stratejileri olsa da hizmet çalışanınız ve isteklerin nasıl işlendiği konusunda sorumluluk size aittir. Bu seçeneklerin hiçbiri ihtiyaçlarınıza uygun değilse kendi planınızı oluşturun.

Örneğin, güncellenmiş içeriğe öncelik vermek için zaman aşımı içeren bir ağ öncelikli strateji kullanabilirsiniz. Ancak bu stratejiyi yalnızca yanıt, belirlediğiniz bir eşik içinde görünüyorsa kullanabilirsiniz. Ayrıca, önbelleğe alınmış bir yanıtı bir ağ yanıtıyla birleştirebilir ve hizmet çalışanından karmaşık bir yanıt oluşturabilirsiniz.

Öğeleri güncelleme

PWA'nızın önbelleğe alınmış öğelerini güncel tutmak zor olabilir. Bunu yapmanın bir yolu, geçersiz olduğunda yeniden doğrulama stratejisidir ancak tek yolu bu değildir. Güncelleme bölümünde, uygulamanızın içeriğini ve öğelerini güncel tutmaya yönelik farklı teknikler öğreneceksiniz.

Kaynaklar