Service Worker'ları içeren sayfalarda güncellemeler yayınlama

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

Bazı senaryolarda hizmet çalışanının belirli bir etkinliği bildirmek için kontrol ettiği etkin sekmelerden herhangi biriyle proaktif olarak iletişim kurması gerekebilir. Örnekler:

  • Service Worker'ın yeni bir sürümü yüklendiğinde kullanıcıya yeni işleve hemen erişebilmesi için "Yenilemek için güncelle" düğmesi görüntülenebilir.
  • "Uygulama artık çevrimdışı çalışmaya hazır" veya "Kullanılabilir içeriğin yeni sürümü" gibi bir gösterge göstererek, hizmet çalışanı tarafında önbelleğe alınmış verilerde gerçekleşen bir değişikliği kullanıcıya bildirme.
Bir hizmet çalışanının güncelleme göndermek için sayfayla iletişim kurduğunu gösteren şema.

Service Worker'ın iletişim başlatmak için sayfadan mesaj almasını gerekmeyen bu kullanım alanlarını "güncellemeleri yayınla" olarak adlandıracağız. Bu kılavuzda, standart tarayıcı API'lerini ve Workbox kitaplığını kullanarak sayfalar ve Service Worker'lar arasında bu tür bir iletişimin uygulanmasının farklı yollarını inceleyeceğiz.

Üretim durumları

Tinder

Tinder PWA, sayfadaki hizmet çalışanı yaşam döngüsündeki önemli anları ("yüklendi", "kontrol edildi" ve "etkinleştirildi") dinlemek için workbox-window kullanır. Böylece yeni bir hizmet çalışanı devreye girdiğinde "Güncelleme Mevcut" banner'ı gösterilir. Böylece çalışan PWA'yı yenileyip en son özelliklere erişebilir:

Tinder'ın web uygulaması "Güncelleme Mevcut" işlevinin ekran görüntüsü.
Tinder PWA'da hizmet çalışanı sayfaya yeni bir sürümün hazır olduğunu bildirir ve sayfada kullanıcılara bir "Güncelleme Mevcut" banner'ı gösterilir.

Squoosh Dili

Squoosh PWA'da, Service Worker çevrimdışı çalışması için gerekli tüm öğeleri önbelleğe aldığı zaman sayfaya "Çevrimdışı çalışmaya hazır" durum bilgisini gösteren bir mesaj göndererek kullanıcıya özellik hakkında bilgi verir:

Squoosh web uygulaması "Çevrimdışı çalışmaya hazır" işlevinin ekran görüntüsü.
Squoosh PWA'da hizmet çalışanı, önbellek hazır olduğunda sayfaya bir güncelleme yayınlar ve sayfada "Çevrimdışı çalışmaya hazır" durum mesajı gösterilir.

Workbox'ı kullanma

Service Worker'ın yaşam döngüsü olaylarını dinleme

workbox-window, önemli hizmet çalışanı yaşam döngüsü olaylarını dinlemek için basit bir arayüz sağlar. Temelde kitaplık, updatefound ve statechange gibi istemci tarafı API'lerini kullanır ve workbox-window nesnesinde daha yüksek düzeyli etkinlik işleyiciler sağlayarak kullanıcının bu etkinlikleri tüketmesini kolaylaştırır.

Aşağıdaki sayfa kodu, Service Worker'ın yeni bir sürümünün yüklendiğini tespit etmenizi ve böylece kullanıcıya iletebilmenizi sağlar:

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

wb.addEventListener('installed', (event) => {
  if (event.isUpdate) {
    // Show "Update App" banner
  }
});

wb.register();

Önbellek verilerindeki değişiklikleri sayfaya bildir

workbox-broadcast-update Workbox paketi, önbelleğe alınmış bir yanıtın güncellendiğini pencere istemcilerine bildirmek için standart bir yol sunar. Bu, en yaygın olarak StaleAmountReverify stratejisi ile birlikte kullanılır.

Güncellemeleri yayınlamak için Service Worker tarafındaki strateji seçeneklerinize broadcastUpdate.BroadcastUpdatePlugin ekleyin:

import {registerRoute} from 'workbox-routing';
import {StaleWhileRevalidate} from 'workbox-strategies';
import {BroadcastUpdatePlugin} from 'workbox-broadcast-update';

registerRoute(
  ({url}) => url.pathname.startsWith('/api/'),
  new StaleWhileRevalidate({
    plugins: [
      new BroadcastUpdatePlugin(),
    ],
  })
);

Web uygulamanızda bu etkinlikleri aşağıdaki gibi dinleyebilirsiniz:

navigator.serviceWorker.addEventListener('message', async (event) => {
  // Optional: ensure the message came from workbox-broadcast-update
  if (event.data.meta === 'workbox-broadcast-update') {
    const {cacheName, updatedUrl} = event.data.payload;

    // Do something with cacheName and updatedUrl.
    // For example, get the cached content and update
    // the content on the page.
    const cache = await caches.open(cacheName);
    const updatedResponse = await cache.match(updatedUrl);
    const updatedText = await updatedResponse.text();
  }
});

Tarayıcı API'lerini kullanma

Workbox'ın sağladığı işlevler ihtiyaçlarınız için yeterli değilse "yayın güncellemeleri" uygulamak için aşağıdaki tarayıcı API'lerini kullanın:

Yayın Kanalı API'sı

Hizmet çalışanı bir BroadcastChannel nesnesi oluşturur ve buna mesajlar göndermeye başlar. Bu mesajları almakla ilgilenen herhangi bir bağlam (ör. sayfa), bir BroadcastChannel nesnesini örnekleyebilir ve mesajları almak için bir mesaj işleyici uygulayabilir.

Yeni bir Service Worker yüklendiğinde sayfayı bilgilendirmek için aşağıdaki kodu kullanın:

// Create Broadcast Channel to send messages to the page
const broadcast = new BroadcastChannel('sw-update-channel');

self.addEventListener('install', function (event) {
  // Inform the page every time a new service worker is installed
  broadcast.postMessage({type: 'CRITICAL_SW_UPDATE'});
});

Sayfa, sw-update-channel abonesi olarak şu etkinlikleri dinler:

// Create Broadcast Channel and listen to messages sent to it
const broadcast = new BroadcastChannel('sw-update-channel');

broadcast.onmessage = (event) => {
  if (event.data && event.data.type === 'CRITICAL_SW_UPDATE') {
    // Show "update to refresh" banner to the user.
  }
};

Bu basit bir tekniktir ancak tarayıcı desteği ile sınırlıdır: Bu makalenin yazıldığı sırada Safari bu API'yi desteklemiyor.

İstemci API'sı

Client API, bir dizi Client nesnesinde yineleme yaparak Service Worker'dan birden fazla istemciyle iletişim kurmanın basit bir yolunu sunar.

Son odaklanılan sekmeye mesaj göndermek için aşağıdaki Service Worker kodunu kullanın:

// Obtain an array of Window client objects
self.clients.matchAll(options).then(function (clients) {
  if (clients && clients.length) {
    // Respond to last focused tab
    clients[0].postMessage({type: 'MSG_ID'});
  }
});

Sayfa, şu iletilere müdahale etmek için bir ileti işleyici uygular:

// Listen to messages
navigator.serviceWorker.onmessage = (event) => {
     if (event.data && event.data.type === 'MSG_ID') {
         // Process response
   }
};

İstemci API'si, birden fazla etkin sekmeye bilgi yayınlama gibi durumlar için mükemmel bir seçenektir. API, önde gelen tüm tarayıcılar tarafından desteklenir, ancak tüm yöntemleri desteklenmez. Kullanmadan önce tarayıcı desteğini kontrol edin.

Mesaj Kanalı

İleti Kanalı, aralarında bir iletişim kanalı kurulması için sayfadan hizmet çalışanına bir bağlantı noktası geçirerek bir ilk yapılandırma adımını gerektirir. Sayfa bir MessageChannel nesnesini örneklendirir ve postMessage() arayüzü üzerinden Service Worker'a bir bağlantı noktası iletir:

const messageChannel = new MessageChannel();

// Init port
navigator.serviceWorker.controller.postMessage({type: 'PORT_INITIALIZATION'}, [
  messageChannel.port2,
]);

Sayfa, söz konusu bağlantı noktasına bir "onmessage" işleyicisi uygulayarak iletileri dinler:

// Listen to messages
messageChannel.port1.onmessage = (event) => {
  // Process message
};

Service Worker, bağlantı noktasını alır ve buna bir referans kaydeder:

// Initialize
let communicationPort;

self.addEventListener('message', (event) => {
  if (event.data && event.data.type === 'PORT_INITIALIZATION') {
    communicationPort = event.ports[0];
  }
});

Bu noktadan sonra, bağlantı noktasına referansta postMessage() yöntemini çağırarak sayfaya mesaj gönderebilir:

// Communicate
communicationPort.postMessage({type: 'MSG_ID' });

Bağlantı noktalarının başlatılması nedeniyle MessageChannel uygulamasının uygulanması daha karmaşık olabilir ancak tüm önemli tarayıcılar tarafından desteklenir.

Sonraki adımlar

Bu kılavuzda, pencereden hizmet çalışanına iletişimin belirli bir örneğini inceledik: "güncellemeleri yayınla". İncelenen örnekler arasında önemli hizmet çalışanı yaşam döngüsü olaylarının dinlenmesi ve içerikteki veya önbelleğe alınan verilerdeki değişiklikler hakkında sayfayla iletişim kurulması bulunur. Service Worker'ın önceden mesaj almadan, sayfayla proaktif olarak iletişim kurduğu daha ilginç kullanım alanları düşünebilirsiniz.

Window ve Service Worker iletişiminin diğer kalıpları için şunlara göz atın:

  • Zorunlu önbelleğe alma kılavuzu: Kaynakları önceden önbelleğe almak için sayfadan bir hizmet çalışanının çağrılması (ör. önceden getirme senaryolarında).
  • İki yönlü iletişim: Bir hizmet çalışanına görev için yetki verme (ör. ağır bir indirme) ve sayfayı süreç hakkında bilgilendirme.

Ek kaynaklar