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

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

Bazı senaryolarda Service Worker'ın, belirli bir olay hakkında bilgi vermek için kontrol ettiği etkin sekmelerle proaktif olarak iletişim kurması gerekebilir. Örnekler:

  • Hizmet çalışanının yeni bir sürümü yüklendiğinde sayfayı bilgilendirerek sayfanın, kullanıcıya yeni işleve hemen erişmesi için "Yenilemek için güncelle" düğmesi gösterebilmesi.
  • Service Worker tarafında önbelleğe alınan verilerde meydana gelen değişiklik hakkında kullanıcıyı bilgilendirir. Bunun için "Uygulama artık çevrimdışı çalışmaya hazır" veya "İçeriğin yeni sürümü mevcut" gibi bir gösterge görüntüleyebilir.
Güncelleme göndermek için sayfayla iletişim kuran bir hizmet çalışanının gösterildiği şema.

Hizmet çalışanının iletişim başlatmak için sayfadan mesaj alması gerekmeyen bu tür kullanım alanlarına "yayın güncellemeleri" adını vereceğiz. Bu kılavuzda, standart tarayıcı API'lerini ve Workbox kitaplığını kullanarak sayfalar ve hizmet çalışanları arasında bu tür bir iletişimi uygulamanın farklı yöntemlerini inceleyeceğiz.

Üretim durumları

Tinder

Tinder PWA, sayfadaki önemli hizmet çalışanı yaşam döngüsü anlarını ("yüklendi", "denetlendi" ve "etkinleştirildi") dinlemek için workbox-window kullanır. Bu şekilde, yeni bir hizmet çalışanı söz konusu olduğunda bir "Güncelleme Mevcut" banner'ı gösterir. Böylece çalışan PWA'yı yenileyebilir ve en son özelliklere erişebilir:

Tinder'ın web uygulamasındaki "Güncelleme Var" 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 sayfa kullanıcılara "Güncelleme Var" banner'ı gösterir.

Squoosh

Squoosh PWA'da hizmet çalışanı, uygulamanın çevrimdışı çalışmasını sağlamak için gerekli tüm öğeleri önbelleğe aldığında sayfaya bir mesaj göndererek "Çevrimdışı çalışmaya hazır" bildirimini gösterir ve kullanıcıya bu özellikten bahseder:

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

Workbox'u kullanma

Hizmet çalışanı yaşam döngüsü etkinliklerini dinleme

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

Aşağıdaki sayfa kodu, hizmet çalışanının yeni bir sürümü her yüklendiğinde bunu algılamanıza olanak tanır. Böylece, bunu kullanıcıya bildirebilirsiniz:

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

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

wb.register();

Sayfayı önbellek verilerindeki değişiklikler hakkında bilgilendirme

Workbox paketiworkbox-broadcast-update pencere istemcilerini, önbelleğe alınmış bir yanıtın güncellendiği konusunda bilgilendirmenin standart bir yolunu sağlar. Bu strateji, genellikle StaleWhileRevalidate stratejisiyle birlikte kullanılır.

Güncellemeleri yayınlamak için hizmet çalışanı tarafındaki strateji seçeneklerinize bir 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'un sağladığı işlevler ihtiyaçlarınıza yetmiyorsa "yayın güncellemeleri" uygulamak için aşağıdaki tarayıcı API'lerini kullanın:

Broadcast Channel API

Hizmet çalışanı bir BroadcastChannel nesnesi oluşturur ve bu nesneye mesaj göndermeye başlar. Bu mesajları almak isteyen tüm bağlamlar (ör. sayfa), bir BroadcastChannel nesnesi oluşturabilir ve mesajları almak için bir mesaj işleyici uygulayabilir.

Yeni bir hizmet çalışanı 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'ye abone olarak bu 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 bununla ilgili sınırlama, tarayıcı desteğidir: Bu yazı yazıldığında Safari bu API'yi desteklememektedir.

İstemci API'si

İstemci API'si, bir dizi Client nesnesi üzerinde iterasyon yaparak hizmet işçisinden birden fazla istemciyle iletişim kurmanın basit bir yolunu sağlar.

Odaklanılan son 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, bu mesajları durdurmak için bir mesaj 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 sekmede bilgi yayınlama gibi durumlar için mükemmel bir seçenektir. API, tüm büyük tarayıcılar tarafından desteklenir ancak API'nin tüm yöntemleri desteklenmez. Kullanmadan önce tarayıcı desteğini kontrol edin.

Mesaj Kanalı

Mesaj Kanalı, aralarında bir iletişim kanalı oluşturmak için sayfadan hizmet çalışanına bir bağlantı noktası geçirerek ilk yapılandırma adımını gerektirir. Sayfa bir MessageChannel nesnesi oluşturur ve postMessage() arayüzü aracılığıyla hizmet çalışanına bir bağlantı noktası iletir:

const messageChannel = new MessageChannel();

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

Sayfa, bu bağlantı noktasına bir "onmessage" işleyici uygulayarak mesajları dinler:

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

Hizmet çalışanı bağlantı noktasını alır ve bağlantı noktasına referans kaydeder:

// Initialize
let communicationPort;

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

Bu noktadan itibaren, bağlantı noktasına referans olarak postMessage() çağrılarak sayfaya mesaj gönderilebilir:

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

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

Sonraki adımlar

Bu kılavuzda, pencere ile hizmet çalışanı arasındaki iletişimin belirli bir örneğini inceledik: "yayın güncellemeleri". İncelenen örnekler arasında önemli hizmet çalışanı yaşam döngüsü etkinliklerini dinleme ve içerik veya önbelleğe alınmış verilerdeki değişikliklerle ilgili sayfaya iletişim kurma yer alır. Hizmet çalışanının daha önce herhangi bir mesaj almadan sayfayla proaktif olarak iletişim kurduğu daha ilginç kullanım alanları düşünebilirsiniz.

Pencere ve hizmet çalışanı iletişimleriyle ilgili diğer kalıplar için aşağıdaki makalelere göz atın:

  • Zorunlu önbelleğe alma kılavuzu: Kaynakları önceden önbelleğe almak için sayfadan bir hizmet çalışanı çağırma (ör. ön getirme senaryolarında).
  • İ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.

Ek kaynaklar