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

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

Bazı durumlarda, hizmet çalışanının belirli bir etkinlik hakkında bilgi vermek için kontrol ettiği etkin sekmelerden herhangi biriyle 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.
  • "Uygulama artık çevrimdışı çalışmaya hazır" veya "İçeriğin yeni sürümü kullanıma sunuldu" gibi bir gösterge göstererek kullanıcıya hizmet çalışanı tarafında önbelleğe alınmış verilerde yapılan bir değişiklik hakkında bilgi verin.
Bir hizmet çalışanının güncelleme göndermek için sayfayla iletişim kurduğunu gösteren diyagram.

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 ile hizmet çalışanları arasında bu tür bir iletişimi uygulamanın farklı yollarını 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 sayede, yeni bir hizmet çalışanı devreye girdiğinde kullanıcılara "Güncelleme Var" banner'ı gösterilir. Böylece kullanıcılar PWA'yı yenileyebilir ve en yeni ö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 haberdar eder:

Squoosh web uygulamasının "Çevrimdışı çalışmaya hazır" işlevinin ekran görüntüsü.
Squoosh PWA'da, önbellek hazır olduğunda hizmet çalışanı sayfaya bir güncelleme yayınlar ve sayfada "Çevrimdışı çalışmaya hazır" bildirimi 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. Kitaplık, updatefound ve statechange gibi istemci tarafı API'leri kullanır ve workbox-window nesnesinde daha üst düzey etkinlik dinleyicileri sağlar. Böylece kullanıcının bu etkinlikleri kullanması kolaylaşı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ı önbelleğe alınan verilerdeki 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 tarayıcıyı destekleme sınırlaması vardır: Bu makalenin yazıldığı sırada Safari bu API'yi desteklemiyor.

Client API

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

Son odaklanan sekmeye mesaj göndermek için aşağıdaki hizmet çalışanı 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ı engellemek 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ı, sayfadan hizmet işleyiciye bir bağlantı noktası aktararak aralarında bir iletişim kanalı oluşturmak için ilk yapılandırma adımı 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ında 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' });

MessageChannel, bağlantı noktalarını başlatma ihtiyacı nedeniyle uygulamak daha karmaşık olabilir ancak tüm büyük 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şimi için daha fazla kalıp görmek isterseniz:

  • 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