Trasmissione di aggiornamenti alle pagine con i service worker

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

In alcuni scenari il service worker potrebbe dover comunicare in modo proattivo con uno qualsiasi le schede che controlla per informare di un determinato evento. Ecco alcuni esempi:

  • Informare la pagina quando è stata installata una nuova versione del service worker, in modo che la pagina puoi mostrare all'utente un pulsante "Aggiorna per aggiornare" per accedere alla nuova funzionalità immediatamente.
  • Informare l'utente di una modifica ai dati memorizzati nella cache che ha avuto luogo sul lato del service worker, che mostra un'indicazione, ad esempio: "L'app è ora pronta per funzionare offline" o "Nuova versione del contenuti disponibili".
Diagramma che mostra un service worker che comunica con la pagina per inviare un aggiornamento.

Chiameremo questi tipi di casi d'uso in cui il service worker non ha bisogno di ricevere un messaggio la pagina per avviare una comunicazione "trasmetti aggiornamenti". In questa guida esamineremo diverse per implementare questo tipo di comunicazione tra le pagine e i service worker, utilizzando API del browser e la libreria Workbox.

Casi di produzione

Compasso

La PWA Tinder utilizza workbox-window per ascoltare importanti momenti del ciclo di vita dei service worker dalla pagina ("installato", "controllato" e "attivato"). In questo modo, quando entra in gioco un nuovo service worker, viene mostrato un "Aggiornamento disponibile". banner, per poter aggiornare la PWA e accedere alle funzionalità più recenti:

Uno screenshot "Aggiornamento disponibile" dell'app web di Tinder funzionalità.
Nella PWA Tinder, il service worker indica alla pagina che è pronta una nuova versione e la pagina mostra agli utenti un messaggio "Aggiornamento disponibile" .

Squoosh

Nella PWA Squoosh, quando il service worker ha memorizzato nella cache tutti i necessari asset per funzionare offline, viene inviato un messaggio alla pagina con la dicitura "Pronto per lavorare offline" toast, per informare l'utente di questa funzionalità:

Uno screenshot dell'app web Squoosh "Ready to work offline" funzionalità.
Nella PWA Squoosh, il service worker trasmette un aggiornamento alla pagina quando la cache è pronta e la pagina visualizza "Pronto per lavorare offline" toast.

Utilizzo di Workbox

Ascolta gli eventi del ciclo di vita dei service worker

workbox-window offre un'interfaccia semplice per ascoltare il ciclo di vita importante dei service worker eventi. Di base, la libreria utilizza API lato client come updatefound e statechange e fornisce listener di eventi di livello superiore nell'oggetto workbox-window, semplificando di consumare questi eventi.

Il codice della pagina seguente consente di rilevare l'installazione di una nuova versione del service worker, per poterlo comunicare all'utente:

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

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

wb.register();

Comunica alla pagina le modifiche ai dati della cache

Pacchetto Workbox workbox-broadcast-update fornisce un metodo standard per informare i client finestra che una risposta memorizzata nella cache è stata aggiornata. Questo è più comunemente utilizzata insieme allo strumento StaleSebbeneRevalidate strategia di offerta.

Per trasmettere aggiornamenti, aggiungi un broadcastUpdate.BroadcastUpdatePlugin alle opzioni della tua strategia nel lato service worker:

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(),
    ],
  })
);

Nella tua app web, puoi ascoltare questi eventi, ad esempio:

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();
  }
});

Utilizzo delle API del browser

Se la funzionalità fornita da Workbox non è sufficiente per le tue esigenze, utilizza il seguente browser API per implementare gli "aggiornamenti della trasmissione":

API Broadcast Channel

Il service worker crea un canale BroadcastChannel oggetto e inizia a inviare messaggi inviati e ricevuti. Qualsiasi contesto (ad esempio, pagina) interessato a ricevere questi messaggi può creare un'istanza di una BroadcastChannel e implementa un gestore di messaggi per ricevere i messaggi.

Per informare la pagina quando viene installato un nuovo service worker, utilizza il codice seguente:

// 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'});
});

La pagina ascolta questi eventi iscrivendosi a sw-update-channel:

// 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.
  }
};

Si tratta di una tecnica semplice, ma il suo limite riguarda il supporto del browser: al momento della stesura del presente documento, Safari non supporta questa API.

API client

L'API client offre un'interfaccia comunicare con più client dal service worker tramite l'iterazione su un array di Client.

Utilizza il seguente codice del service worker per inviare un messaggio all'ultima scheda attiva:

// 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'});
  }
});

La pagina implementa un gestore di messaggi per intercettare questi messaggi:

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

L'API client è un'ottima opzione per casi come la trasmissione di informazioni a più schede attive. La L'API è supportata da tutti i principali browser, ma non tutti i suoi metodi lo sono. Verifica il supporto del browser prima di utilizzandolo.

Canale messaggi

Message Channel richiede un passaggio di configurazione iniziale, passando una porta dalla pagina al service worker, per stabilire canale di comunicazione tra di loro. La pagina crea un'istanza di un oggetto MessageChannel e passa un al service worker, tramite l'interfaccia postMessage():

const messageChannel = new MessageChannel();

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

La pagina ascolta i messaggi implementando un messaggio "onmessage" su quella porta:

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

Il service worker riceve la porta e vi salva un riferimento:

// Initialize
let communicationPort;

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

A quel punto può inviare messaggi alla pagina, chiamando postMessage() nel riferimento al porta:

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

MessageChannel potrebbe essere più complesso da implementare per via della necessità di inizializzare le porte, ma supportate da tutti i principali browser.

Passaggi successivi

In questa guida abbiamo esplorato un caso particolare della comunicazione Window to Service worker: "aggiornamenti della trasmissione". Gli esempi esplorati includono l'ascolto di un service worker importante eventi del ciclo di vita e comunicano alla pagina modifiche ai contenuti o ai dati memorizzati nella cache. Puoi pensare di casi d'uso più interessanti in cui il service worker comunica in modo proattivo con la pagina, senza aver ricevuto nessun messaggio in precedenza.

Per ulteriori modelli di comunicazione tra Windows e Service worker, dai un'occhiata qui:

Risorse aggiuntive