zorunluluk önbelleğe alma kılavuzu

Andrew Guan
Andrew Guan
Demián Renzulli
Demián Renzulli

Bazı web sitelerinin, sonuç hakkında bilgilendirilmeden hizmet işçisiyle iletişim kurması gerekebilir. Aşağıda bazı örnekler verilmiştir:

  • Bir sayfa, hizmet çalışanına önceden önbelleğe alınacak URL'lerin listesini gönderir. Böylece kullanıcı bir bağlantıyı tıkladığında doküman veya sayfa alt kaynakları önbellekte hazır olur ve sonraki gezinme çok daha hızlı olur.
  • Sayfa, hizmet çalışanından en çok okunan makaleleri alıp önbelleğe almasını ve böylece çevrimdışı olarak kullanılabilmesini ister.

Kritik olmayan bu tür görevleri hizmet işleyiciye devretmek, ana iş parçacığının kullanıcı etkileşimlerine yanıt verme gibi daha acil görevleri daha iyi işleyebilmesi için boşaltılmasını sağlar.

Bir hizmet çalışanına önbelleğe alınması için kaynak isteyen sayfanın şeması.

Bu rehberde, standart tarayıcı API'lerini ve Workbox kitaplığını kullanarak sayfadan hizmet işleyiciye tek yönlü bir iletişim tekniğinin nasıl uygulanacağını inceleyeceğiz. Bu tür kullanım alanlarını zorunlu önbelleğe alma olarak adlandıracağız.

Üretim destek kaydı

1-800-Flowers.com, kategori sayfalarındaki en popüler öğeleri önceden almak ve ardından ürün ayrıntıları sayfalarına gitmeyi hızlandırmak için postMessage() aracılığıyla hizmet işçileriyle zorunlu önbelleğe alma (ön yükleme) özelliğini uyguladı.

1-800 Flowers logosu.

Hangi öğelerin önceden belleneceğine karar vermek için karma bir yaklaşım kullanırlar:

  • Sayfa yüklenirken servis sağlayıcı çalışanından en iyi 9 öğenin JSON verilerini almasını ve elde edilen yanıt nesnelerini önbelleğe eklemesini ister.
  • Kalan öğeler için mouseover etkinliğini dinlerler. Böylece, kullanıcı imleci bir öğenin üzerine getirdiğinde "talep" üzerine kaynak için getirme işlemini tetikleyebilirler.

JSON yanıtlarını depolamak için Cache API'yi kullanırlar:

1-800 Flowers logosu.
1-800Flowers.com'daki ürün listeleme sayfalarından JSON ürün verilerini önceden getirme

Kullanıcı bir öğeyi tıkladığında, ağ bağlantısına gerek kalmadan öğeyle ilişkili JSON verileri önbellekten alınabilir. Bu da gezinmeyi hızlandırır.

Workbox'u kullanma

Workbox, pencere bağlamında çalışacak bir modül grubu olan workbox-window paketi aracılığıyla bir hizmet çalışanına mesaj göndermenin kolay bir yolunu sağlar. Bunlar, servis çalışanında çalışan diğer Workbox paketlerini tamamlar.

Sayfayı service worker ile iletişime geçirmek için önce kayıtlı service worker'a ait bir Workbox nesne referansı alın:

const wb = new Workbox('/sw.js');
wb
.register();

Ardından, kayıt alma, etkinleştirmeyi kontrol etme veya temel iletişim API'sini düşünme zahmetine girmeden mesajı doğrudan beyanla gönderebilirsiniz:

wb.messageSW({"type": "PREFETCH", "payload": {"urls": ["/data1.json", "data2.json"]}}); });

Hizmet çalışanı, bu mesajları dinlemek için bir message işleyici uygular. İsteğe bağlı olarak bir yanıt döndürebilir ancak bu gibi durumlarda gerekli değildir:

self.addEventListener('message', (event) => {
 
if (event.data && event.data.type === 'PREFETCH') {
   
// do something
 
}
});

Tarayıcı API'lerini kullanma

Workbox kitaplığı ihtiyaçlarınız için yeterli değilse tarayıcı API'lerini kullanarak pencereden hizmet işçisine iletişimi nasıl uygulayabileceğinizi burada bulabilirsiniz.

postMessage API, sayfadan hizmet işleyiciye tek yönlü bir iletişim mekanizması oluşturmak için kullanılabilir.

Sayfa, hizmet çalışanı arayüzünde postMessage() çağrısı yapıyor:

navigator.serviceWorker.controller.postMessage({
  type
: 'MSG_ID',
  payload
: 'some data to perform the task',
});

Hizmet çalışanı, bu mesajları dinlemek için bir message işleyici uygular.

self.addEventListener('message', (event) => {
 
if (event.data && event.data.type === MSG_ID) {
   
// do something
 
}
});

{type : 'MSG_ID'} özelliği kesinlikle gerekli değildir ancak sayfanın hizmet çalışanına farklı türde talimatlar göndermesine (ör. "önceden getirme" ve "depolama alanını temizleme") izin vermenin bir yoludur. Hizmet çalışanı, bu işarete bağlı olarak farklı yürütme yollarına ayrılabilir.

İşlem başarılı olursa kullanıcı bu durumdan yararlanabilir. İşlem başarısız olursa ana kullanıcı akışında değişiklik olmaz. Örneğin, 1-800-Flowers.com ön önbelleğe almaya çalıştığında sayfanın, hizmet çalışanının başarılı olup olmadığını bilmesi gerekmez. Bu durumda kullanıcı daha hızlı gezinme deneyimi yaşar. Aksi takdirde sayfanın yeni sayfaya yönlendirilmesi gerekir. Bu işlem biraz daha sürecek.

Basit bir ön getirme örneği

Zorunlu önbelleğe alma'nın en yaygın uygulamalarından biri ön beslemedir. Bu, kullanıcı ilgili URL'ye geçmeden önce, gezinmeyi hızlandırmak için söz konusu URL'nin kaynaklarını getirme anlamına gelir.

Sitelerde ön getirmeyi uygulamanın farklı yolları vardır:

Belgelerin veya belirli öğelerin (JS, CSS vb.) önceden yüklenmesi gibi nispeten basit ön yükleme senaryoları için bu teknikler en iyi yaklaşımdır.

Ek mantık gerekiyorsa (ör. dahili URL'lerini almak için ön getirme kaynağını (JSON dosyası veya sayfa) ayrıştırma) bu görevi tamamen hizmet işleyiciye devretmek daha uygundur.

Bu tür işlemleri hizmet işleyiciye devretmenin avantajları şunlardır:

  • Getirme ve getirme sonrası işleme (daha sonra kullanıma sunulacaktır) işlemlerinin ağır yükünü ikincil bir iş parçacığına aktarma. Bu sayede ana iş parçacığı, kullanıcı etkileşimlerine yanıt vermek gibi daha önemli görevleri yerine getirmek için özgür kalır.
  • Birden fazla istemcinin (ör. sekmeler) ortak bir işlevi yeniden kullanmasına izin verme ve hatta ana iş parçacığı engellenmeden hizmeti aynı anda çağırma.

Ürün ayrıntıları sayfalarını önceden getirme

Öncelikle hizmet çalışanı arayüzünde postMessage() kullanın ve önbelleğe alınacak bir URL dizisi iletin:

navigator.serviceWorker.controller.postMessage({
  type
: 'PREFETCH',
  payload
: {
    urls
: [
     
'www.exmaple.com/apis/data_1.json',
     
'www.exmaple.com/apis/data_2.json',
   
],
 
},
});

Hizmet çalışanında, etkin bir sekme tarafından gönderilen iletileri yakalayıp işlemek için bir message işleyici uygulayın:

addEventListener('message', (event) => {
  let data
= event.data;
 
if (data && data.type === 'PREFETCH') {
    let urls
= data.payload.urls;
   
for (let i in urls) {
      fetchAsync
(urls[i]);
   
}
 
}
});

Önceki kodda, URL dizisini iterlemek ve her biri için bir getirme isteği göndermek üzere fetchAsync() adlı küçük bir yardımcı işlev tanıtmıştık:

async function fetchAsync(url) {
 
// await response of fetch call
  let prefetched
= await fetch(url);
 
// (optionally) cache resources in the service worker storage
}

Yanıt alındığında kaynağın önbelleğe alma üstbilgilerini kullanabilirsiniz. Ancak çoğu durumda (ör. ürün ayrıntıları sayfalarında) kaynaklar önbelleğe alınmaz (yani Cache-control no-cache başlığı vardır). Bu gibi durumlarda, getirilen kaynağı hizmet çalışanı önbelleğine kaydederek bu davranışı geçersiz kılabilirsiniz. Bu, dosyanın çevrimdışı senaryolarda yayınlanmasına olanak tanır.

JSON verilerinin ötesinde

JSON verileri bir sunucu uç noktasından getirildikten sonra genellikle önceden getirmeye değer başka URL'ler de içerir (ör. bu birinci düzey verilerle ilişkili bir resim veya diğer uç nokta verileri).

Örneğimizde, döndürülen JSON verilerinin bir market alışverişi sitesinin bilgileri olduğunu varsayalım:

{
 
"productName": "banana",
 
"productPic": "https://cdn.example.com/product_images/banana.jpeg",
 
"unitPrice": "1.99"
 
}

Ürün listesini iterlemek ve her birinin hero resmini önbelleğe almak için fetchAsync() kodunu değiştirin:

async function fetchAsync(url, postProcess) {
 
// await response of fetch call
  let prefetched
= await fetch(url);

 
//(optionally) cache resource in the service worker cache

 
// carry out the post fetch process if supplied
 
if (postProcess) {
    await postProcess
(prefetched);
 
}
}

async
function postProcess(prefetched) {
  let productJson
= await prefetched.json();
 
if (productJson && productJson.product_pic) {
    fetchAsync
(productJson.product_pic);
 
}
}

404 hataları gibi durumlar için bu kodun etrafına bazı istisna işleme ekleyebilirsiniz. Ancak ön besleme için bir hizmet çalışanı kullanmanın avantajı, sayfa ve ana iş parçacığı için çok fazla soruna yol açmadan başarısız olabilmesidir. Ayrıca, önceden getirilen içeriğin son işleme aşamasında daha ayrıntılı bir mantık kullanabilirsiniz. Bu sayede içeriği daha esnek hale getirebilir ve işlediği verilerden ayırabilirsiniz. Sizi sınırlayan hiçbir şey yok.

Sonuç

Bu makalede, sayfa ile hizmet çalışanı arasında tek yönlü iletişimin yaygın bir kullanım alanını ele aldık: zorunlu önbelleğe alma. Ele alınan örnekler yalnızca bu kalıbın bir kullanım şeklini göstermeyi amaçlamaktadır. Aynı yaklaşım, çevrimdışı tüketim için en popüler makaleleri isteğe bağlı olarak önbelleğe alma, yer işareti ekleme ve diğer kullanım alanları gibi diğer kullanım alanlarına da uygulanabilir.

Sayfa ve hizmet çalışanı iletişimi için daha fazla kalıp görmek isterseniz şu makalelere göz atın:

  • Güncellemeleri yayınlama: Önemli güncellemeler (ör. web uygulamasının yeni bir sürümü kullanıma sunuldu) hakkında bilgi vermek için sayfayı hizmet çalışanından çağırma.
  • İki yönlü iletişim: Bir görevi servis çalışanına devretme (ör. büyük boyutlu bir indirme) ve sayfayı ilerleme durumu hakkında bilgilendirme.