Sunum

Progresif Web Uygulamaları'nın en önemli özelliklerinden biri güvenilirdir. Öğeleri hızlı bir şekilde yükleyerek kötü ağ koşullarında bile kullanıcıların ilgisini canlı tutabilir ve anında geri bildirim verebilir. Peki bu nasıl mümkün oluyor? Hizmet çalışanı fetch etkinliği sayesinde.

Tarayıcı Desteği

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

Kaynak

fetch etkinliği, hem aynı kaynaklı hem de kaynaklar arası istekler için hizmet çalışanı kapsamında PWA tarafından yapılan her ağ isteğini yakalamamıza olanak tanır. Gezinme ve öğe isteklerine ek olarak, yüklü bir hizmet çalışanından getirmek, bir sitenin ilk yüklemesinin ardından sayfa ziyaretlerinin ağ çağrıları olmadan oluşturulmasına olanak tanır.

fetch işleyici, URL'ler ve HTTP üst bilgileri de dahil olmak üzere bir uygulamadan gelen tüm istekleri alır ve bunların nasıl işleneceğine uygulama geliştiricisinin karar vermesine izin verir.

Service Worker, istemci ile ağ arasında durur.

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ış. Aşağıda basit bir örnek verilmiştir:

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

Bir isteği yanıtlama

Service Worker'ınıza bir istek geldiğinde yapabileceğiniz iki şey vardır: bunu göz ardı edebilirsiniz. Bu durumda ağa gidebilir veya ona yanıt verebilirsiniz. Kullanıcı çevrimdışı olduğunda bile hizmet çalışanınızdan gelen isteklere yanıt vererek neyin ve nasıl PWA'nıza döndürüleceğini seçebilirsiniz.

Gelen bir isteği yanıtlamak için fetch etkinlik işleyicisinin içinden şu şekilde event.respondWith() çağırın:

// 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() öğesini eşzamanlı olarak çağırmanız ve bir Yanıt nesnesi döndürmeniz gerekir. Ancak, getirme etkinlik işleyicisi bittikten sonra (ör. eşzamansız bir çağrıda) respondWith() işlevini çağıramazsınız. Yanıtın tamamını beklemeniz gerekiyorsa respondWith() adlı kullanıcıya sözü iletebilirsiniz. Söz konusu işlem için yanıt geldiğinde yanıt verilir.

Yanıtlar oluşturuluyor

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

Yanıt oluşturmak için gövdesini ve durum ile üstbilgiler gibi seçenekleri ayarlayarak yeni bir Response nesnesi oluşturun:

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

Artık bir Service Worker'dan HTTP yanıtlarını almayı bildiğinize göre sıra, öğeleri cihazda depolamak için Depolama Alanı arayüzünü kullanmaya geldi.

PWA'dan alınan isteğin önbellekte olup olmadığını kontrol etmek için önbellek depolama API'sini kullanabilirsiniz. İstek önbellekte bulunuyorsa respondWith() uygulamasına bununla yanıt verebilirsiniz. Bunu yapmak için önce önbellek içinde arama yapmanız gerekir. En üst düzey caches arayüzünde bulunan match() işlevi, kaynağınızdaki tüm depolarda veya tek bir açık önbellek nesnesinde arama yapar.

match() işlevi, bağımsız değişken olarak bir HTTP isteği veya URL alır ve karşılık gelen anahtarla ilişkilendirilmiş Yanıtla çözümlenen bir taahhüt 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ın yalnızca tarayıcı önbelleğinden sunulması her kullanım alanına uygun olmayabilir. Örneğin, kullanıcı veya tarayıcı önbelleği çıkarabilir. İşte bu yüzden PWA'nız için öğe yayınlama stratejilerinizi tanımlamanız gerekir. Tek bir önbelleğe alma stratejisiyle sınırlı değilsiniz. Farklı URL kalıpları için farklı reklam öğeleri tanımlayabilirsiniz. Örneğin, minimum kullanıcı arayüzü öğeleri, API çağrıları için bir başka, resim ve veri URL'leri için bir üçüncü stratejiniz olabilir. Bunu yapmak için ServiceWorkerGlobalScope.onfetch içindeki event.request.url bölümünü okuyun ve normal ifadeler veya URL Kalıbı ile ayrıştırın. (URL Kalıbı, yazıldığı sırada tüm platformlarda desteklenmemektedir).

En yaygın stratejiler şunlardır:

Önce Önbellek
Önce önbelleğe alınmış bir yanıt arar ve bulunamazsa ağa geri döner.
Önce Ağ
Önce ağdan bir yanıt ister. Yanıt döndürülmezse önbellekteki yanıt olup olmadığını kontrol eder.
Yeniden Doğrulama Sırasında Eski
Önbellekten yanıt sunarken arka planda en son sürüm istenir ve öğe tekrar istendiğinde önbellek içine kaydedilir.
Yalnızca Ağ
Her zaman ağdan veya hatadan yanıt vererek yanıt verir. Önbelleğe hiçbir zaman başvurulmaz.
Yalnızca Önbellek
Her zaman önbellekten yanıt verir veya hata verir. Ağa hiçbir zaman danışılmaz. Bu strateji kullanılarak sunulacak öğeler, istenmeden önce önbelleğe eklenmelidir.

Önce önbelleğe alın

Service Worker, 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üncelleme yoluyla). Önbellek yanıtı veya ağ yanıtı yoksa istek hata verir. Öğeleri ağa gitmeden yayınlamak daha hızlı olma eğiliminde olduğundan bu strateji, güncellik yerine performansa öncelik verir.

Önce Önbellek 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);
     }
   )
  )
});

Önce ağ

Bu strateji, "Önce Önbellek" stratejisinin aynasıdır; isteğin ağdan karşılanıp karşılanmadığını kontrol eder ve yerine getirilemiyorsa isteği önbellekten almaya çalışır. Önce önbellek gibidir. Ağ yanıtı veya önbellek yanıtı yoksa istek hata verir. Ağdan yanıt almak, önbellekten yanıt almaktan genellikle daha yavaştır. Bu strateji, performans yerine güncellenmiş içeriğe öncelik verir.

Önce Ağ stratejisi

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

Yeniden doğrulanırken eskilendi

Yeniden doğrulama stratejisi, önbelleğe alınmış bir yanıtı hemen döndürür, ardından ağda bir güncelleme olup olmadığını kontrol eder ve varsa önbelleğe alınan yanıtı değiştirir. Bu strateji her zaman ağ isteğinde bulunur. Çünkü önbelleğe alınmış bir kaynak bulunsa bile, bir sonraki istekte güncellenmiş sürümü kullanmak için önbellekte bulunanları ağdan alınan bilgilerle güncellemeye çalışır. Dolayısıyla bu strateji, önce önbellek stratejisinin hızlı sunumundan yararlanmanız ve önbelleği arka planda güncellemeniz için bir yol sağlar.

Stratejiyi yeniden doğrularken gösterilen eskilik

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, bir hizmet çalışanı veya Cache Storage API olmadan tarayıcıların davranış şekline benzer. İstekler yalnızca ağdan getirilebilen bir kaynağı döndürür. Bu genellikle yalnızca online API istekleri gibi kaynaklar için yararlı olur.

Yalnızca ağ stratejisi

Yalnızca önbellek

Yalnızca önbellek stratejisi, isteklerin hiçbir zaman ağa gitmemesini sağlar. Tüm gelen istekler, önceden doldurulmuş bir önbellek öğesiyle yanıtlanır. Aşağıdaki kod yalnızca önbelleği yanıtlamak için önbellek 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ıdaki yaygın önbelleğe alma stratejileri olsa da hizmet çalışanınız ve isteklerin nasıl işlendiği sizin kontrolünüzdedir. Bunların hiçbiri ihtiyaçlarınıza uygun değilse kendi çözümünüzü oluşturun.

Örneğin, yalnızca yanıt belirlediğiniz eşik dahilinde gösteriliyorsa güncellenmiş içeriğe öncelik vermek için zaman aşımı olan bir ilk ağ stratejisi kullanabilirsiniz. Ayrıca önbelleğe alınmış bir yanıtı ağ yanıtıyla birleştirebilir ve hizmet çalışanından karmaşık bir yanıt oluşturabilirsiniz.

Öğeler güncelleniyor

PWA'nızın önbelleğe alınan öğelerini güncel tutmak zor olabilir. Yeniden doğrulama stratejisi eskileri, bunun bir yolu olsa da tek yöntem değildir. Güncelleme bölümünde, uygulamanızın içeriğini ve öğelerini güncel tutmak için farklı teknikler öğreneceksiniz.

Kaynaklar