Diffuser des mises à jour sur les pages avec des service workers

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

Dans certains cas, le service worker doit communiquer de manière proactive avec l'un des services onglets qu'il commande pour signaler un événement particulier. Voici quelques exemples :

  • Informer la page lorsqu'une nouvelle version du service worker a été installée, afin que la page Possibilité d'afficher un bouton Mettre à jour pour actualiser afin que l'utilisateur puisse accéder à la nouvelle fonctionnalité immédiatement.
  • Pour informer l'utilisateur d'une modification des données mises en cache effectuée côté service worker, indiquant un message du type "L'application est désormais prête à fonctionner hors connexion" ou "Nouvelle version du contenu disponible.
Schéma illustrant un service worker communiquant avec la page pour envoyer une mise à jour.

Nous appellerons ce type de cas d'utilisation où le service worker n'a pas besoin de recevoir un message la page pour lancer une communication "notifications de diffusion". Dans ce guide, nous passerons en revue différents d'implémenter ce type de communication entre les pages et les service workers, à l'aide d'outils standards et la bibliothèque Workbox.

Cas de production

Tinder

La PWA Tinder utilise workbox-window pour écouter les moments importants du cycle de vie d'un service worker sur la page ("installé", "contrôlé" et "activée"). Ainsi, lorsqu'un nouveau service worker entre en jeu, une mise à jour disponible s'affiche. afin qu'ils puissent actualiser la PWA et accéder aux dernières fonctionnalités:

<ph type="x-smartling-placeholder">
</ph> Capture d&#39;écran de l&#39;application Web &quot;Mise à jour disponible&quot; de Tinder de Google Cloud.
Dans la PWA Tinder, le service worker indique à la page qu'une nouvelle version est prête, et la page affiche le message "Update available" (Mise à jour disponible). .

Squoosh

Dans la PWA Squoosh, lorsque le service worker a mis en cache toutes les ressources pour qu'elle fonctionne hors connexion, le message "Prêt à fonctionner hors connexion" s'affiche sur la page un toast pour informer l'utilisateur de la fonctionnalité:

<ph type="x-smartling-placeholder">
</ph> Capture d&#39;écran de l&#39;application Web Squoosh &quot;Prêt pour le travail hors connexion&quot; de Google Cloud.
Dans la PWA Squoosh, le service worker diffuse une mise à jour de la page lorsque le cache est prêt et que la page affiche "Prêt à fonctionner hors connexion". une tartine grillée.

Utiliser Workbox

Écouter les événements de cycle de vie d'un service worker

workbox-window fournit une interface simple pour écouter le cycle de vie d'un service worker important. les événements. En arrière-plan, la bibliothèque utilise des API côté client telles que updatefound et statechange et fournit des écouteurs d'événements de niveau supérieur dans l'objet workbox-window, ce qui facilite d'utiliser ces événements.

Le code de page suivant vous permet de détecter chaque installation d'une nouvelle version du service worker : afin de pouvoir le communiquer à l'utilisateur:

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

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

wb.register();

Informer la page des modifications apportées aux données mises en cache

Package Workbox workbox-broadcast-update permet d'informer les clients de la fenêtre qu'une réponse mise en cache a été mise à jour. C'est généralement utilisé avec le service StalewhileRevalidate stratégie d'enchères.

Pour diffuser des actualités, ajoutez un broadcastUpdate.BroadcastUpdatePlugin à vos options de stratégie dans le côté 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(),
    ],
  })
);

Dans votre application Web, vous pouvez écouter les événements suivants:

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

Utiliser les API du navigateur

Si les fonctionnalités proposées par Workbox ne répondent pas à vos besoins, utilisez le navigateur suivant : API permettant d'implémenter les mises à jour de diffusion:

API Broadcast Channel

Le service worker crée un objet BroadcastChannel objet et commence à envoyer des messages. Tout contexte (par exemple, une page) intéressé par la réception de ces messages peut instancier BroadcastChannel et implémentez un gestionnaire de messages pour recevoir des messages.

Pour informer la page lorsqu'un nouveau service worker est installé, utilisez le code suivant:

// 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 page écoute ces événements en s'abonnant à 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.
  }
};

Bien qu'il s'agisse d'une technique simple, la compatibilité avec les navigateurs est limitée. Au moment de la rédaction de ce document, Safari n'est pas compatible avec cette API.

API cliente

L'API cliente fournit un outil simple moyen de communication avec plusieurs clients depuis le service worker en effectuant une itération sur un tableau de Objets Client.

Le code de service worker suivant permet d'envoyer un message au dernier onglet sélectionné:

// 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 page implémente un gestionnaire de messages pour intercepter ces messages:

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

L'API cliente est une excellente option pour diffuser des informations dans plusieurs onglets actifs, par exemple. La L'API est compatible avec tous les principaux navigateurs, mais pas toutes ses méthodes. Vérifiez la compatibilité des navigateurs avant l'utilisent.

Canal de messagerie

Message Channel requiert une étape de configuration initiale, qui consiste à transmettre un port de la page au service worker afin d'établir une de communication entre eux. La page instancie un objet MessageChannel et transmet une vers le service worker, via l'interface postMessage():

const messageChannel = new MessageChannel();

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

La page écoute les messages en implémentant une instruction "onmessage" sur ce port:

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

Le service worker reçoit le port et enregistre une référence à celui-ci:

// Initialize
let communicationPort;

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

À ce stade, il peut envoyer des messages à la page en appelant postMessage() dans la référence à la port:

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

MessageChannel peut être plus complexe à implémenter en raison de la nécessité d'initialiser des ports, mais il est compatible avec les principaux navigateurs.

Étapes suivantes

Dans ce guide, nous avons étudié un cas particulier de communication entre les équipes de service et de fenêtre: "informations concernant la diffusion". Les exemples étudiés incluent l'écoute d'importants service worker des événements du cycle de vie et la communication avec la page en cas de modifications du contenu ou des données mises en cache. Vous pouvez réfléchir de cas d'utilisation plus intéressants où le service worker communique de manière proactive avec la page, sans recevoir de message auparavant.

Pour découvrir d'autres modèles de communication entre Windows et les service workers, consultez la page suivante:

  • Guide de mise en cache impérative: appeler un service worker depuis la page vers mettre en cache les ressources à l'avance (par exemple, dans les scénarios de préchargement).
  • Communication bidirectionnelle: déléguer une tâche à un service worker (par exemple, un téléchargement important) et tenir la page informée de la progression.

Ressources supplémentaires