Aktualisierungen an Seiten mit Service Workern senden

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

In einigen Szenarien muss der Service Worker proaktiv mit einem der aktiven werden, um über bestimmte Ereignisse informiert zu werden. Beispiele:

  • Seite informieren, wenn eine neue Version des Service Workers installiert wurde, damit die Seite kann dem Nutzer die Schaltfläche Update zum Aktualisieren anzeigen, um auf die neue Funktion zuzugreifen. sofort.
  • Sie informieren den Nutzer über eine Änderung an den im Cache gespeicherten Daten, die vom Service Worker durchgeführt wurde, indem eine Anzeige wie diese wird angezeigt: „Die App kann jetzt offline verwendet werden.“ oder „Neue Version des Inhalte verfügbar“.
Diagramm, das einen Service Worker zeigt, der mit der Seite kommuniziert, um ein Update zu senden

Wir nennen diese Arten von Anwendungsfällen, bei denen der Service Worker keine Nachricht von die Seite, um die Kommunikation mit Updates zu senden zu starten. In diesem Leitfaden behandeln wir verschiedene Möglichkeiten zur Implementierung dieser Art der Kommunikation zwischen den Seiten und Service Workern mithilfe von Browser-APIs und der Workbox-Bibliothek

Produktionsfälle

Tinder

Die Tinder-PWA verwendet workbox-window zum Anhören von in wichtigen Momenten des Service Worker-Lebenszyklus („installiert“, „gesteuert“ „aktiviert“). Wenn dann ein neuer Service Worker ins Spiel kommt, wird die Meldung Update verfügbar angezeigt. Banner, damit sie die PWA aktualisieren und auf die neuesten Funktionen zugreifen können:

<ph type="x-smartling-placeholder">
</ph> Screenshot der Webanwendung „Update verfügbar“ von Tinder Funktionalität.
In der Tinder-PWA teilt der Service Worker der Seite mit, dass eine neue Version verfügbar ist, und auf der Seite wird den Nutzern die Meldung „Update verfügbar“ angezeigt. Banner.

Squoosh

Wenn der Service Worker in der Squoosh-PWA alle erforderlichen damit es offline verwendet werden kann, wird eine Meldung an die Seite gesendet, Toast an und informiert die Nutzenden über die Funktion:

<ph type="x-smartling-placeholder">
</ph> Screenshot von Squoosh Web-App &quot;Bereit für die Offline-Arbeit&quot; Funktionalität.
In der Squoosh-PWA sendet der Service Worker ein Update an die Seite, sobald der Cache bereit ist, und auf der Seite wird „Bereit für die Offline-Arbeit“ angezeigt. Toast.

Workbox verwenden

Service Worker-Lebenszyklusereignisse überwachen

workbox-window bietet eine einfache Schnittstelle, mit der der wichtige Service Worker-Lebenszyklus überwacht werden kann Events Intern nutzt die Bibliothek clientseitige APIs wie updatefound und statechange und stellt Ereignis-Listener auf höherer Ebene im workbox-window-Objekt bereit, was den um diese Ereignisse zu verarbeiten.

Mit dem folgenden Seitencode erkennen Sie, wann eine neue Version des Service Workers installiert wird, damit Sie es den Nutzenden mitteilen können:

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

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

wb.register();

Seite über Änderungen an Cache-Daten informieren

Das Workbox-Paket workbox-broadcast-update bietet eine Standardmethode, um Window-Clients zu benachrichtigen, dass eine im Cache gespeicherte Antwort aktualisiert wurde. Dies ist am häufigsten in Verbindung mit der Methode StaleOnceRevalidation" verwendet Strategie.

Füge zum Übertragen von Aktualisierungen ein broadcastUpdate.BroadcastUpdatePlugin zu deinen Strategieoptionen in der Service Worker-Seite:

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

In Ihrer Webanwendung können Sie beispielsweise auf folgende Ereignisse warten:

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

Browser-APIs verwenden

Wenn die von Workbox bereitgestellte Funktionalität für Ihre Anforderungen nicht ausreicht, verwenden Sie den folgenden Browser. APIs zur Implementierung von Broadcast-Updates:

Broadcast-Channel-API

Der Service Worker erstellt einen BroadcastChannel Objekt und sendet das Nachrichten an sie senden. Jeder Kontext (z.B. eine Seite), der am Erhalt dieser Nachrichten interessiert ist, kann ein BroadcastChannel-Objekt und implementieren Sie einen Nachrichten-Handler, um Nachrichten zu empfangen.

Verwenden Sie den folgenden Code, um die Seite zu informieren, wenn ein neuer Service Worker installiert wird:

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

Die Seite erfasst diese Ereignisse, indem sie sw-update-channel abonniert:

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

Dies ist eine einfache Methode, aber ihre Einschränkung ist die Browserunterstützung: Safari unterstützt diese API nicht.

Client-API

Die Client API bietet eine einfache Art der Kommunikation mit mehreren Clients vom Service Worker durch Iteration über ein Array von Client-Objekten

Verwenden Sie den folgenden Service Worker-Code, um eine Nachricht an den letzten hervorgehobenen Tab zu senden:

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

Auf der Seite wird ein Nachrichten-Handler implementiert, um diese Nachrichten abzufangen:

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

Die Client API eignet sich hervorragend für Fälle wie das Übertragen von Informationen an mehrere aktive Tabs. Die Das API wird von allen gängigen Browsern unterstützt, nicht alle Methoden jedoch. Browserunterstützung vor dem verwenden.

Kanal für Nachrichten

Message Channel erfordert einen ersten Konfigurationsschritt, indem Sie einen Port von der Seite an den Service Worker übergeben, um einen Kommunikationskanal zwischen ihnen. Die Seite instanziiert ein MessageChannel-Objekt und übergibt ein an den Service Worker über die Schnittstelle postMessage() an:

const messageChannel = new MessageChannel();

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

Die Seite hört Nachrichten ab, indem ein „onmessage“ implementiert wird Handler an diesem Port:

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

Der Service Worker empfängt den Port und speichert einen Verweis darauf:

// Initialize
let communicationPort;

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

Ab diesem Zeitpunkt können Nachrichten an die Seite gesendet werden, indem postMessage() im Verweis auf die Port:

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

MessageChannel ist möglicherweise komplexer zu implementieren, da Ports initialisiert werden müssen. die von allen gängigen Browsern unterstützt werden.

Nächste Schritte

In diesem Leitfaden haben wir einen speziellen Fall der Window-zu-Service-Worker-Kommunikation untersucht: "broadcast updates" (Übertragungsupdates). Zu den untersuchten Beispielen gehört das Überwachen von wichtigen Service Workern Lebenszyklus-Ereignisse und Kommunizieren der Seite über Änderungen von Inhalten oder im Cache gespeicherten Daten. Sie können darüber nachdenken, Anwendungsfälle, bei denen der Service Worker proaktiv mit der Seite kommuniziert, ohne vorher eine Nachricht zu erhalten.

Weitere Muster für die Window- und Service Worker-Kommunikation finden Sie hier:

  • Leitfaden zum imperativen Caching: Service Worker von der Seite aus aufrufen, im Voraus im Cache speichern (z.B. beim Vorabruf).
  • Zwei-Wege-Kommunikation: Aufgaben an einen Service Worker delegieren (z.B. ein umfangreicher Download) und die Seite über den Fortschritt auf dem Laufenden zu halten.

Zusätzliche Ressourcen