Start · Sprachen · JavaScript · Referenz · ServiceWorkerRegistration.update()

ServiceWorkerRegistration.update()

Methode

Lädt das Skript des Service Workers sofort neu vom Server und installiert eine neue Version, falls sich die Skriptdatei Byte für Byte geändert hat.

seit JavaScript Baseline: alle modernen Browser (Chrome 45+, Firef Kategorie: webapi

Signatur

ServiceWorkerRegistration.prototype.update()

Beschreibung

update() startet von Hand eine Update-Prüfung für eine Service-Worker-Registrierung. Der Browser lädt dazu die Skript-URL des Workers neu und vergleicht sie Byte für Byte mit der installierten Version. Wenn sich etwas geändert hat, installiert er einen neuen Worker. Dieser erscheint zuerst unter registration.installing und danach unter registration.waiting. Ist das Skript unverändert, passiert nichts.

Von sich aus prüft der Browser nur bei Navigationen innerhalb des Scopes, bei bestimmten funktionalen Events (etwa push oder sync) und höchstens alle 24 Stunden auf Updates. Mit update() kannst du öfter prüfen. Das lohnt sich vor allem bei langlebigen Single-Page-Anwendungen, die tagelang offen bleiben und selten neu navigieren.

Der neue Worker wird nicht sofort aktiv. Er wartet, bis keine Seite mehr vom alten Worker gesteuert wird, außer er ruft self.skipWaiting() auf. Um Nutzern eine neue Version anzuzeigen, reagierst du deshalb meist auf das Event updatefound und den Statuswechsel des neuen Workers.

Ob beim Neuladen der HTTP-Cache genutzt wird, legt die Option updateViaCache von navigator.serviceWorker.register() fest. Der Standardwert 'imports' umgeht den Cache für das Hauptskript.

Rückgabewert

Typ
Promise<ServiceWorkerRegistration | undefined>
Beschreibung
Ein Promise, das erfüllt wird, sobald die Update-Prüfung abgeschlossen ist, also das Skript geladen und verglichen wurde. Je nach Browser und Stand der Spezifikation erhältst du die ServiceWorkerRegistration oder undefined. Werte das Ergebnis also nicht aus, sondern lies den Zustand direkt aus der Registrierung. Das Promise wird abgelehnt, wenn das Skript nicht geladen werden kann (TypeError, z. B. bei Netzwerkfehler oder 404) oder die Registrierung nicht mehr gültig ist (InvalidStateError).

Beispiele

Einmalige Update-Prüfung auslösen

const checkForUpdate = async () => {
  const registration = await navigator.serviceWorker.getRegistration();
  if (!registration) {
    console.log('Kein Service Worker registriert.');
    return;
  }
  try {
    await registration.update();
    console.log('Update-Prüfung abgeschlossen.');
    if (registration.installing || registration.waiting) {
      console.log('Neue Version gefunden.');
    }
  } catch (err) {
    console.error('Update fehlgeschlagen:', err.name, err.message);
  }
};

checkForUpdate();
Update-Prüfung abgeschlossen. Neue Version gefunden.

Regelmäßig prüfen in einer langlebigen SPA

const registration = await navigator.serviceWorker.register('/sw.js');

// Stündlich prüfen, aber nur wenn online und der Tab sichtbar ist
const ONE_HOUR = 60 * 60 * 1000;
setInterval(() => {
  if (navigator.onLine && document.visibilityState === 'visible') {
    registration.update().catch((err) => console.warn('Update-Check:', err));
  }
}, ONE_HOUR);

// Zusätzlich prüfen, wenn der Nutzer zum Tab zurückkehrt
document.addEventListener('visibilitychange', () => {
  if (document.visibilityState === 'visible') {
    registration.update().catch(() => {});
  }
});

Neue Version erkennen und per Klick aktivieren

// Seite (main.js)
const registration = await navigator.serviceWorker.register('/sw.js');

registration.addEventListener('updatefound', () => {
  const newWorker = registration.installing;
  newWorker.addEventListener('statechange', () => {
    // 'installed' + vorhandener controller = Update, keine Erstinstallation
    if (newWorker.state === 'installed' && navigator.serviceWorker.controller) {
      if (confirm('Neue Version verfügbar. Jetzt neu laden?')) {
        newWorker.postMessage({ type: 'SKIP_WAITING' });
      }
    }
  });
});

navigator.serviceWorker.addEventListener('controllerchange', () => {
  window.location.reload();
});

document.querySelector('#check-update')
  .addEventListener('click', () => registration.update());

// Service Worker (sw.js)
// self.addEventListener('message', (event) => {
//   if (event.data?.type === 'SKIP_WAITING') self.skipWaiting();
// });

// Wichtig · Fallstricke

  • Nur Byte-Vergleich des Hauptskripts: Ein Update wird nur erkannt, wenn sich sw.js selbst ändert oder, je nach updateViaCache, ein per importScripts() geladenes Skript. Geänderte Assets wie CSS oder JS-Bundles lösen kein Update aus. Trage deshalb eine Versionsnummer oder einen Hash in den Worker ein.
  • HTTP-Cache: Mit updateViaCache: 'all' kann update() eine veraltete Version aus dem HTTP-Cache bekommen. Liefere sw.js am besten mit Cache-Control: no-cache oder max-age=0 aus.
  • Keine sofortige Aktivierung: Wenn das Promise erfüllt ist, ist der neue Worker höchstens installiert, aber nicht aktiv. Für die Aktivierung brauchst du skipWaiting() oder das Schließen aller Tabs. Lade nach controllerchange neu, damit Seite und Worker zusammenpassen.
  • Fehlerbehandlung: Offline oder bei einem 404 wird das Promise mit TypeError abgelehnt. Fang Aufrufe in Intervallen immer mit .catch() ab, sonst tauchen unbehandelte Promise-Ablehnungen in der Konsole auf.
  • Nicht zu oft aufrufen: Jeder Aufruf ist eine Netzwerkanfrage. Minütliches Abfragen belastet Server und Akku unnötig.
  • Kompatibilität: Service Worker gibt es nur in sicheren Kontexten (HTTPS oder localhost). Der Rückgabewert des Promise unterscheidet sich zwischen den Browsern (Registrierung oder undefined).