Hizmet çalışanı önbelleğe alma stratejileri

Şimdiye kadar bunlardan yalnızca bahsediliyor ve küçük kod snippet'leri Cache arayüzü. Service Worker'ları etkili bir şekilde kullanmak için bir veya daha fazla önbelleğe alma stratejisi benimsenmeli, Bunun için Cache arayüzü hakkında biraz bilgi sahibi olmanız gerekir.

Önbelleğe alma stratejisi, bir hizmet çalışanının fetch etkinliği ile Cache arayüzü arasındaki etkileşimdir. Önbelleğe alma stratejisinin nasıl yazıldığına bağlıdır; Statik öğelere yönelik isteklerin, belgelerden farklı şekilde ele alınması tercih edilebilir. Bu da önbelleğe alma stratejisinin oluşturulma şeklini etkiler.

Stratejilere geçmeden önce Şimdi Cache arayüzünün ne olmadığından, ne olduğundan bahsedelim. ve Service Worker önbelleklerini yönetmek için sunduğu yöntemlerden bazıları kısaca özetlenmiştir.

Cache arayüzü ile HTTP önbelleği karşılaştırması

Daha önce Cache arayüzüyle çalışmadıysanız size en uygun seçenek, veya en azından HTTP önbelleğiyle alakalı olmalıdır. Böyle bir durum söz konusu değildir.

  • Cache arayüzü, HTTP önbelleğinden tamamen ayrı bir önbelleğe alma mekanizmasıdır.
  • Her neyse Cache-Control HTTP önbelleğini etkilemek için kullandığınız yapılandırmanın Cache arayüzünde hangi öğelerin depolanacağı üzerinde herhangi bir etkisi yoktur.

Tarayıcı önbelleklerini katmanlı olarak düşünebilirsiniz. HTTP önbelleği, HTTP başlıklarında ifade edilen yönergeler içeren anahtar/değer çiftleri tarafından yönlendirilen düşük düzeyli bir önbellektir.

Buna karşılık Cache arayüzü, JavaScript API'si tarafından kullanılan üst düzey bir önbellektir. Bu, nispeten basit HTTP anahtar/değer çiftlerini kullanmaya kıyasla daha fazla esneklik sağlar. ve önbelleğe alma stratejilerini mümkün kılan şeylerin yarısı. Service Worker önbelleklerine ilişkin bazı önemli API yöntemleri şunlardır:

  • CacheStorage.open kullanarak yeni bir Cache örneği oluşturun.
  • Cache.add ve Cache.put hizmet çalışanı önbelleğinde depolamak için kullanılır.
  • Cache.match Cache örneğinde önbelleğe alınmış yanıtı bulmak için kullanılır.
  • Cache.delete Cache örneğinden önbelleğe alınan yanıtı kaldırın.

Müşterilerimizden birkaçı aşağıda yer alıyor. Başka faydalı yöntemler de vardır, ancak bunlar, bu kılavuzun ilerleyen bölümlerinde göreceğiniz temel özelliklerdir.

Mütevazı fetch etkinliği

Önbelleğe alma stratejisinin diğer yarısı, hizmet çalışanının fetch etkinliği. Şu ana kadar bu belgede "ağ isteklerine müdahale etme", Service Worker'daki fetch etkinliği ise şu şekilde gerçekleşir:

// Establish a cache name
const cacheName = 'MyFancyCacheName_v1';

self.addEventListener('install', (event) => {
  event.waitUntil(caches.open(cacheName));
});

self.addEventListener('fetch', async (event) => {
  // Is this a request for an image?
  if (event.request.destination === 'image') {
    // Open the cache
    event.respondWith(caches.open(cacheName).then((cache) => {
      // Respond with the image from the cache or from the network
      return cache.match(event.request).then((cachedResponse) => {
        return cachedResponse || fetch(event.request.url).then((fetchedResponse) => {
          // Add the network response to the cache for future visits.
          // Note: we need to make a copy of the response to save it in
          // the cache and use the original as the request response.
          cache.put(event.request, fetchedResponse.clone());

          // Return the network response
          return fetchedResponse;
        });
      });
    }));
  } else {
    return;
  }
});

Bu bir oyuncak örneğidir. birini kendi gözlerinizle görün, Service Worker'ların neler yapabileceğine dair fikir sunar. Yukarıdaki kod şunları yapar:

  1. Bunun bir resim isteği olup olmadığını görmek için isteğin destination özelliğini inceleyin.
  2. Resim, hizmet çalışanı önbelleğindeyse buradan yayınlayın. Değilse resmi ağdan getirin, yanıtı önbellekte saklar ve ağ yanıtını döndürür.
  3. Diğer tüm istekler, önbellekle herhangi bir etkileşim olmadan hizmet çalışanı üzerinden iletilir.

Bir getirmenin event nesnesi, request mülk istek türünü belirlemenize yardımcı olacak yararlı bilgileri içerir:

  • url fetch etkinliği tarafından işlenen ağ isteğinin URL'sidir.
  • method Bu, istek yöntemi (ör. GET veya POST).
  • mode Bu açıklama, isteğin modunu açıklar. 'navigate' değeri, genellikle HTML dokümanı isteklerini diğer isteklerden ayırt etmek için kullanılır.
  • destination belirtin.

Bir kez daha belirtmek gerekirse, oyunun adı eşzamansız install etkinliğinin event.waitUntil bir yöntem olarak bilinen ve etkinleştirmeye devam etmeden önce çözümün tamamlanmasını bekler. fetch etkinliği benzer bir etkinlik sunuyor event.respondWith yöntem eşzamansız bir sorgunun sonucunu döndürmek için kullanabileceğiniz fetch istek veya Cache arayüzünün match yöntemini kullanın.

Önbelleğe alma stratejileri

Artık Cache örnekleri ve fetch etkinlik işleyicisi hakkında bilgi sahibi olduğunuza göre, Service Worker önbelleğe alma stratejilerini incelemeye hazırsınız. Olasılıklar neredeyse sonsuz olsa da bu kılavuz Workbox ile birlikte sunulan stratejilerde Böylece Workbox'ın dahili ayarlarında neler olduğu hakkında fikir edinebilirsiniz.

Yalnızca önbellek

Sayfadan hizmet çalışanına ve önbelleğe kadar olan akışı gösterir.

"Yalnızca Önbellek" adını vereceğimiz basit bir önbellek stratejisiyle başlayalım. Dahası, hizmet çalışanı sayfanın kontrolünde olduğunda eşleşen istekler her zaman yalnızca önbelleğe gider. Bu, kalıbın çalışması için önbelleğe alınan tüm öğelerin önceden önbelleğe alınması gerektiği anlamına gelir. ve hizmet çalışanı güncellenene kadar bu öğelerin hiçbir zaman önbellekte güncellenmeyeceğini belirtmek isteriz.

// Establish a cache name
const cacheName = 'MyFancyCacheName_v1';

// Assets to precache
const precachedAssets = [
  '/possum1.jpg',
  '/possum2.jpg',
  '/possum3.jpg',
  '/possum4.jpg'
];

self.addEventListener('install', (event) => {
  // Precache assets on install
  event.waitUntil(caches.open(cacheName).then((cache) => {
    return cache.addAll(precachedAssets);
  }));
});

self.addEventListener('fetch', (event) => {
  // Is this one of our precached assets?
  const url = new URL(event.request.url);
  const isPrecachedRequest = precachedAssets.includes(url.pathname);

  if (isPrecachedRequest) {
    // Grab the precached asset from the cache
    event.respondWith(caches.open(cacheName).then((cache) => {
      return cache.match(event.request.url);
    }));
  } else {
    // Go to the network
    return;
  }
});

Yukarıda, bir öğe dizisi yükleme sırasında önceden önbelleğe alınmış. Hizmet çalışanı getirme işlemlerini gerçekleştirirken fetch etkinliği tarafından işlenen istek URL'sinin, önbelleğe alınmış öğeler dizisinde olup olmadığını kontrol ederiz. Bu durumda kaynağı önbellekten alır ve ağı atlarız. Diğer istekler ağa geçer. yalnızca ağda yer alır. Bu stratejiyi uygulamada görmek için konsolunuz açıkken bu demoya göz atın.

Yalnızca ağ

Sayfadan hizmet çalışanına ve ağa giden akışı gösterir.

"Yalnızca Önbellek"in tersi "Yalnızca Ağ" ise istek, hizmet çalışanı önbelleğiyle herhangi bir etkileşim olmadan, bir hizmet çalışanı aracılığıyla ağa iletilir. Bu, içeriğin güncelliğini sağlamak (işaretlemeyi değil) için iyi bir stratejidir. Ancak bunun karşılığında, kullanıcı çevrimdışıyken de hiçbir zaman çalışmayacaktır.

Bir isteğin ağ üzerinden iletilmesini sağlamak, yalnızca eşleşen bir istek için event.respondWith öğesini çağırmayacağınız anlamına gelir. Açıkça belirtmek istiyorsanız Ağa iletmek istediğiniz istekler için fetch etkinliğinizin geri çağırma özelliğinde boş bir return; yerleştirebilirsiniz. "Yalnızca Önbellek"te olan şey önceden önbelleğe alınmamış istekler için strateji demosu.

Önce önbelleğe alın, ağa geri döner

Sayfadan hizmet çalışanına, önbelleğe alınan sayfaya, önbellekte yoksa ağa giden akışı gösterir.

Bu stratejide işler biraz daha karmaşıktır. Eşleşen istekler için süreç şu şekilde işler:

  1. İstek önbelleğe alınır. Öğe önbellekteyse buradan yayınlayın.
  2. İstek önbellekte yoksa ağa gidin.
  3. Ağ isteği tamamlandığında, isteği önbelleğe ekleyin ve daha sonra ağdan yanıtı döndürür.

Aşağıda, bu stratejinin test edebileceğiniz bir örnek canlı bir demo yapabilirsiniz:

// Establish a cache name
const cacheName = 'MyFancyCacheName_v1';

self.addEventListener('fetch', (event) => {
  // Check if this is a request for an image
  if (event.request.destination === 'image') {
    event.respondWith(caches.open(cacheName).then((cache) => {
      // Go to the cache first
      return cache.match(event.request.url).then((cachedResponse) => {
        // Return a cached response if we have one
        if (cachedResponse) {
          return cachedResponse;
        }

        // Otherwise, hit the network
        return fetch(event.request).then((fetchedResponse) => {
          // Add the network response to the cache for later visits
          cache.put(event.request, fetchedResponse.clone());

          // Return the network response
          return fetchedResponse;
        });
      });
    }));
  } else {
    return;
  }
});

Bu örnek yalnızca resimleri kapsasa da Bu, tüm statik öğelere (CSS, JavaScript, resimler ve yazı tipleri gibi) uygulamak için harika bir stratejidir, özellikle de karma sürümler kullanılıyor. HTTP önbelleğinin başlatabileceği sunucuyla içerik güncelliği kontrollerini atlayarak sabit öğeler için hız artışı sağlar. Daha da önemlisi, önbelleğe alınan tüm öğeler çevrimdışı kullanılabilir olacak.

Önce ağ, sonra önbelleğe alınır

Sayfadan hizmet çalışanına, ağa ve ardından ağ yoksa önbelleğe alma akışını gösterir.

"Önce önbelleğe, sonra ağ"a dönerseniz kafasında "Önce ağ, ikinci önbellek" mesajını görürsünüz stratejisi şöyle olur:

  1. Önce bir istek için ağa gider ve yanıtı önbelleğe yerleştirirsiniz.
  2. Daha sonra çevrimdışı olursanız bu yanıtın önbellekteki en son sürümüne geri dönersiniz.

Bu strateji, şu durumlarda HTML veya API istekleri için idealdir: bir kaynağın en yeni sürümünü kullanmak istiyorsanız henüz en son sürüme çevrimdışı erişim vermek istiyorsanız. HTML isteklerine uygulandığında aşağıdaki gibi görünebilir:

// Establish a cache name
const cacheName = 'MyFancyCacheName_v1';

self.addEventListener('fetch', (event) => {
  // Check if this is a navigation request
  if (event.request.mode === 'navigate') {
    // Open the cache
    event.respondWith(caches.open(cacheName).then((cache) => {
      // Go to the network first
      return fetch(event.request.url).then((fetchedResponse) => {
        cache.put(event.request, fetchedResponse.clone());

        return fetchedResponse;
      }).catch(() => {
        // If the network is unavailable, get
        return cache.match(event.request.url);
      });
    }));
  } else {
    return;
  }
});

Bunu demoda deneyebilirsiniz. Önce sayfaya gidin. HTML yanıtı önbelleğe yerleştirilmeden önce yeniden yüklemeniz gerekebilir. Daha sonra geliştirici araçlarınızda çevrimdışı bağlantı simülasyonu ve tekrar yeniden yükleyin. Kullanılabilir son sürüm, önbellekten anında sunulur.

Çevrimdışı kapasitenin önemli olduğu durumlarda, Ancak bu yeteneği, bir miktar işaretlemenin veya API verilerinin en son sürümüne erişimle dengelemeniz gerekir, "Önce ağ, ikinci önbellek" bu hedefe ulaşan sağlam bir stratejidir.

Yeniden doğrulama sırasında eski tarihli

Sayfadan hizmet çalışanına, önbelleğe, ardından ağdan önbelleğe olan akışı gösterir.

Şu ana kadar işlediğimiz stratejilerden, "Stale-when-reverification" (Sürekli yeniden doğrulama) en karmaşık olanıdır. Son iki stratejiye bazı yönlerden benziyor. Ancak prosedür, kaynak için erişim hızına öncelik verir. arka planda güncel tutar. Bu strateji şöyle bir şeye benziyor:

  1. Bir öğeyi ilk kez istediğinizde, öğeyi ağdan getirin. önbelleğe yerleştirip ağ yanıtını döndürün.
  2. Sonraki isteklerde öğeyi önce önbellekten, ardından "arka planda" sunun. öğeyi ağdan yeniden isteyebilir ve öğenin önbellek girişini güncelleyebilir.
  3. Bundan sonraki istekler için önceki adımda önbelleğe yerleştirilmiş olan ağdan getirilen son sürümü alırsınız.

Bu, takip edilmesi bir düzeyde önemli olan şeyler için mükemmel bir stratejidir, ancak son derece önemli değil. Sosyal medya sitelerindeki avatarlar gibi düşünün. Kullanıcılar değişiklik yaptıkça güncellenir, ancak her istekte en yeni sürüm kesinlikle gerekli değildir.

// Establish a cache name
const cacheName = 'MyFancyCacheName_v1';

self.addEventListener('fetch', (event) => {
  if (event.request.destination === 'image') {
    event.respondWith(caches.open(cacheName).then((cache) => {
      return cache.match(event.request).then((cachedResponse) => {
        const fetchedResponse = fetch(event.request).then((networkResponse) => {
          cache.put(event.request, networkResponse.clone());

          return networkResponse;
        });

        return cachedResponse || fetchedResponse;
      });
    }));
  } else {
    return;
  }
});

Bunun nasıl çalıştığını şurada görebilirsiniz: başka bir canlı demo daha var. özellikle tarayıcınızın geliştirici araçlarındaki ağ sekmesine dikkat ediyorsanız ve CacheStorage görüntüleyici (tarayıcınızın geliştirici araçlarında böyle bir araç varsa).

Workbox'a geçiyoruz!

Bu belgede, Service Worker'ın API'si ve ve ilgili API’leri içerir. Bu, Workbox ile çalışmaya başlamak için Service Worker'ları doğrudan nasıl kullanacağınız konusunda yeterince bilgi edindiğiniz anlamına geliyor!