Çalışma zamanı sırasında kaynakları önbelleğe alma

Web uygulamanızdaki bazı öğeler nadiren kullanılmış, çok büyük olabilir veya kullanıcının cihazına (duyarlı resimler gibi) ya da diline göre değişiklik gösterebilir. Bunlar, önbelleğe almanın bir kalıp dışı olabildiği durumlardır ve bunun yerine çalışma zamanı önbelleğe alma yöntemini kullanmanız gerekir.

Workbox'ta, rotaları eşleştirmek için workbox-routing modülünü kullanarak öğelerin çalışma zamanını önbelleğe alma işlemini ve workbox-strategies modülü ile bunlar için önbelleğe alma stratejilerini işleyebilirsiniz.

Önbelleğe alma stratejileri

Yerleşik önbelleğe alma stratejilerinden biriyle öğeler için çoğu rotayı işleyebilirsiniz. Bunlar, bu belgelerin önceki bölümlerinde ayrıntılı olarak ele alınmıştır ancak aşağıda özetlenen bazı bilgiler verilmiştir:

  • Stale About ReValid, istek için kullanılabiliyorsa önbellekteki yanıtı kullanır ve önbelleği ağdan gelen bir yanıtla günceller. Dolayısıyla, öğe önbelleğe alınmamışsa ağın yanıtını bekler ve kullanır. Kendisine dayanan önbellek girişlerini düzenli olarak güncellediği için bu, oldukça güvenli bir stratejidir. Olumsuz tarafı ise her zaman arka planda ağdan öğe istemesidir.
  • Network First, önce ağdan yanıt almaya çalışır. Bir yanıt alınırsa, bu yanıtı tarayıcıya iletir ve bir önbelleğe kaydeder. Ağ isteği başarısız olursa önbelleğe alınan son yanıt kullanılır ve öğeye çevrimdışı erişim etkinleştirilir.
  • Önce Önbellek, önbelleği öncelikle bir yanıt için kontrol eder ve varsa kullanır. İstek önbellekte değilse ağ kullanılır ve geçerli tüm yanıtlar, tarayıcıya iletilmeden önce önbelleğe eklenir.
  • Yalnızca Ağ, yanıtı ağdan gelmeye zorlar.
  • Yalnızca Önbellek, yanıtı önbellekten gelmeye zorlar.

workbox-routing tarafından sunulan yöntemleri kullanarak belirli istekler için bu stratejileri uygulayabilirsiniz.

Rota eşleştirme ile önbelleğe alma stratejilerini uygulama

workbox-routing, rotaları eşleştirmek ve bir önbelleğe alma stratejisiyle işlemek için bir registerRoute yöntemi sunar. registerRoute, iki bağımsız değişkeni kabul eden Route nesnesini kabul eder:

  1. Rota eşleştirme ölçütlerini belirtmek için kullanılan bir dize, normal ifade veya eşleşme geri çağırması.
  2. Rotanın işleyicisi. Genellikle workbox-strategies tarafından sağlanan stratejidir.

Request nesnesini, istek URL'si dizesini, getirme etkinliğini ve isteğin aynı kaynak istek olup olmadığına dair bir boole değerini içeren bir bağlam nesnesi sağladığından, rotaları eşleştirmek için eşleştirme geri çağırmaları tercih edilir.

Ardından işleyici, eşleşen rotayı işler. Aşağıdaki örnekte, gelen aynı kaynaktan gelen görüntü istekleriyle eşleşen, önce önbelleği ve ağ stratejisine geri dönmek üzere yeni bir rota oluşturulmuştur.

// sw.js
import { registerRoute, Route } from 'workbox-routing';
import { CacheFirst } from 'workbox-strategies';

// A new route that matches same-origin image requests and handles
// them with the cache-first, falling back to network strategy:
const imageRoute = new Route(({ request, sameOrigin }) => {
  return sameOrigin && request.destination === 'image'
}, new CacheFirst());

// Register the new route
registerRoute(imageRoute);

Birden fazla önbellek kullanma

Çalışma kutusu, gruplandırılmış stratejilerde sunulan cacheName seçeneğini kullanarak önbelleğe alınan yanıtları ayrı Cache örneklerinde gruplandırmanıza olanak tanır.

Aşağıdaki örnekte resimler eski bir yeniden doğrulama stratejisi kullanırken CSS ve JavaScript öğeleri önbellek öncelikli ağ stratejisinden yararlanır. Her öğenin rotası, cacheName özelliğini ekleyerek yanıtları ayrı önbelleklere yerleştirir.

// sw.js
import { registerRoute, Route } from 'workbox-routing';
import { CacheFirst, StaleWhileRevalidate } from 'workbox-strategies';

// Handle images:
const imageRoute = new Route(({ request }) => {
  return request.destination === 'image'
}, new StaleWhileRevalidate({
  cacheName: 'images'
}));

// Handle scripts:
const scriptsRoute = new Route(({ request }) => {
  return request.destination === 'script';
}, new CacheFirst({
  cacheName: 'scripts'
}));

// Handle styles:
const stylesRoute = new Route(({ request }) => {
  return request.destination === 'style';
}, new CacheFirst({
  cacheName: 'styles'
}));

// Register routes
registerRoute(imageRoute);
registerRoute(scriptsRoute);
registerRoute(stylesRoute);
Chrome'un Geliştirici Araçları'nın uygulama sekmesindeki Önbellek örnekleri listesinin ekran görüntüsü Üç farklı önbellek gösterilir: Biri 'scripts', diğeri 'styles' ve sonuncusu 'images' olarak adlandırılır.
Chrome Geliştirici Araçları'nın Uygulama panelindeki Önbellek depolama alanı görüntüleyicisi. Farklı öğe türleriyle ilgili yanıtlar ayrı önbelleklerde depolanır.

Önbellek girişleri için süre sonu belirleme

Service Worker önbelleklerini yönetirken depolama alanı kotalarını göz önünde bulundurun. ExpirationPlugin, önbellek bakımını basitleştirir ve workbox-expiration tarafından kullanıma sunulur. Kullanmak için bunu bir önbelleğe alma stratejisinin yapılandırmasında belirtin:

// sw.js
import { registerRoute, Route } from 'workbox-routing';
import { CacheFirst } from 'workbox-strategies';
import { ExpirationPlugin } from 'workbox-expiration';

// Evict image cache entries older thirty days:
const imageRoute = new Route(({ request }) => {
  return request.destination === 'image';
}, new CacheFirst({
  cacheName: 'images',
  plugins: [
    new ExpirationPlugin({
      maxAgeSeconds: 60 * 60 * 24 * 30,
    })
  ]
}));

// Evict the least-used script cache entries when
// the cache has more than 50 entries:
const scriptsRoute = new Route(({ request }) => {
  return request.destination === 'script';
}, new CacheFirst({
  cacheName: 'scripts',
  plugins: [
    new ExpirationPlugin({
      maxEntries: 50,
    })
  ]
}));

// Register routes
registerRoute(imageRoute);
registerRoute(scriptsRoute);

Depolama alanı kotalarına uyum sağlamak karmaşık olabilir. Depolama alanı baskısı yaşayan veya depolama alanından en verimli şekilde yararlanmak isteyen kullanıcıları dikkate almanız önerilir. Workbox'ın ExpirationPlugin çiftleri, bu hedefe ulaşmanıza yardımcı olabilir.

Kaynaklar arası dikkat edilmesi gereken noktalar

Service Worker'ınız ile kaynaklar arası öğeleriniz arasındaki etkileşim, aynı kaynaktaki öğelere kıyasla önemli ölçüde farklıdır. Çapraz Kökenli Kaynak Paylaşımı (CORS) karmaşık bir süreçtir. Bu karmaşıklık, bir Service Worker'da kaynaklar arası kaynakları yönetme biçiminizi de etkiler.

Opak yanıtlar

no-cors modunda kaynaklar arası istek yapılırken yanıt, hizmet çalışanı önbelleğinde depolanabilir, hatta doğrudan tarayıcı tarafından kullanılabilir. Ancak yanıt gövdesinin kendisi JavaScript aracılığıyla okunamaz. Bu, opak yanıt olarak bilinir.

Opak yanıtlar, kaynaklar arası öğenin denetlenmesini önlemeyi amaçlayan güvenlik önlemidir. Kaynaklar arası öğeler için istek göndermeye devam edebilir, hatta bu öğeleri önbelleğe alabilirsiniz. Ancak yanıt gövdesini okuyamaz, hatta durum kodunu bile okuyamazsınız!

CORS modunu etkinleştirmeyi unutmayın

Yanıtları okumanıza izin veren serbest CORS başlıkları ayarlayan kaynaklar arası öğeler yükleseniz bile, kaynaklar arası yanıtın gövdesi yine opak olabilir. Örneğin, aşağıdaki HTML, hangi CORS başlıklarının ayarlandığından bağımsız olarak opak yanıtlara yol açacak no-cors isteklerini tetikler:

<link rel="stylesheet" href="https://example.com/path/to/style.css">
<img src="https://example.com/path/to/image.png">

Opak olmayan bir yanıt verecek cors isteğini açık bir şekilde tetiklemek için HTML'nize crossorigin özelliğini ekleyerek CORS modunu açıkça etkinleştirmeniz gerekir:

<link crossorigin="anonymous" rel="stylesheet" href="https://example.com/path/to/style.css">
<img crossorigin="anonymous" src="https://example.com/path/to/image.png">

Hizmet çalışanınızdaki rotaların, çalışma zamanında yüklenen alt kaynaklarını önbelleğe aldığı zamanların hatırlanması önemlidir.

Çalışma kutusu, opak yanıtları önbelleğe almayabilir

Varsayılan olarak Workbox, opak yanıtları önbelleğe alma konusunda temkinli bir yaklaşım benimser. Opak yanıtlar için yanıt kodunu incelemek imkansız olduğundan, önbellek öncelikli veya yalnızca önbellek stratejisi kullanılırsa bir hata yanıtının önbelleğe alınması, sürekli olarak bozuk bir deneyime neden olabilir.

Workbox'ta opak bir yanıtı önbelleğe almanız gerekiyorsa bunu işlemek için ağ öncelikli veya eski doğrulama stratejisi kullanmanız gerekir. Evet, bu, öğenin her zaman ağdan isteneceği anlamına gelir ancak başarısız yanıtların devam etmesini ve sonunda kullanılabilir yanıtlarla değiştirilmesini sağlar.

Başka bir önbelleğe alma stratejisi kullanırsanız ve opak bir yanıt döndürülürse Workbox, geliştirme modundayken yanıtın önbelleğe alınamadığı konusunda sizi uyarır.

Opak yanıtların önbelleğe alınmasını zorunlu kıl

Önbellek öncelikli veya yalnızca önbelleğe alınmış bir strateji kullanarak opak bir yanıtı önbelleğe almak istediğinizden kesinlikle eminseniz workbox-cacheable-response modülü ile Workbox'ı bunu yapmaya zorlayabilirsiniz:

import {Route, registerRoute} from 'workbox-routing';
import {NetworkFirst, StaleWhileRevalidate} from 'workbox-strategies';
import {CacheableResponsePlugin} from 'workbox-cacheable-response';

const cdnRoute = new Route(({url}) => {
  return url === 'https://cdn.google.com/example-script.min.js';
}, new CacheFirst({
  plugins: [
    new CacheableResponsePlugin({
      statuses: [0, 200]
    })
  ]
}))

registerRoute(cdnRoute);

Donuk Yanıtlar ve navigator.storage API

Alanlar arası bilgilerin sızdırılmasını önlemek amacıyla, depolama alanı kota sınırlarını hesaplamak için kullanılan opak yanıtın boyutuna önemli miktarda dolgu eklenir. Bu durum, navigator.storage API'nin depolama alanı kotalarını nasıl raporlayacağını etkiler.

Bu dolgu tarayıcıya göre değişir ancak Chrome için, önbelleğe alınmış opak tek bir yanıtın kullanılan toplam depolama alanına katkıda bulunduğu minimum boyut yaklaşık 7 megabayttır. Kaç opak yanıtı önbelleğe almak istediğinize karar verirken bu durumu göz önünde bulundurmalısınız. Çünkü depolama alanı kotalarını normalde beklediğinizden çok daha erken aşabilirsiniz.