Signatur
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
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();
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.jsselbst ändert oder, je nachupdateViaCache, ein perimportScripts()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'kannupdate()eine veraltete Version aus dem HTTP-Cache bekommen. Lieferesw.jsam besten mitCache-Control: no-cacheodermax-age=0aus. - 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 nachcontrollerchangeneu, damit Seite und Worker zusammenpassen. - Fehlerbehandlung: Offline oder bei einem 404 wird das Promise mit
TypeErrorabgelehnt. 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 oderundefined).