Signatur
Beschreibung
Normalerweise bleibt ein neu installierter Service Worker im Zustand waiting, solange noch mindestens ein Client (Tab, Fenster, iframe) vom bisher aktiven Worker kontrolliert wird. Erst wenn alle diese Clients geschlossen oder weg-navigiert sind, wird die neue Version aktiviert. skipWaiting() überspringt diese Wartephase: Der neue Worker wird aktiviert, sobald er fertig installiert ist.
Die Methode wird im Kontext des Service Workers aufgerufen (self.skipWaiting()). Das geschieht meist im install-Event oder, wenn die Seite den Nutzer vorher fragen soll, in einem message-Handler, sobald die Seite ein „Jetzt aktualisieren“-Signal schickt. Der Aufruf kann jederzeit erfolgen. Wirksam wird er aber nur, wenn gerade ein Worker installiert wird oder bereits wartet.
Oft wird skipWaiting() zusammen mit Clients.claim() im activate-Event benutzt. Dann übernimmt der neue Worker auch die bereits geöffneten Seiten sofort, statt erst beim nächsten Laden.
Achtung: Nach skipWaiting() können geöffnete Seiten, die noch mit altem HTML oder JavaScript laufen, auf einmal von einem neuen Worker mit neuen Caches bedient werden. Ohne passende Strategie (z. B. Seite neu laden über das controllerchange-Event) kann es dadurch zu Versionskonflikten kommen.
Rückgabewert
undefined erfüllt wird, sobald der Aufruf angenommen wurde. Es wartet nicht, bis die Aktivierung abgeschlossen ist.Beispiele
Neue Version sofort aktivieren (install + activate)
// sw.js
const CACHE = 'app-v2';
self.addEventListener('install', (event) => {
// Wartephase überspringen, das Ergebnis muss nicht abgewartet werden
self.skipWaiting();
event.waitUntil(
caches.open(CACHE).then((cache) => cache.addAll(['/', '/app.js', '/style.css']))
);
});
self.addEventListener('activate', (event) => {
event.waitUntil((async () => {
// Alte Caches entfernen
const keys = await caches.keys();
await Promise.all(keys.filter((k) => k !== CACHE).map((k) => caches.delete(k)));
// Bereits geöffnete Seiten sofort übernehmen
await self.clients.claim();
console.log('Neuer Service Worker aktiv');
})());
});
Update erst nach Bestätigung durch den Nutzer
// sw.js
self.addEventListener('message', (event) => {
if (event.data?.type === 'SKIP_WAITING') {
self.skipWaiting();
}
});
// main.js (Seite)
const reg = await navigator.serviceWorker.register('/sw.js');
const promptUpdate = (worker) => {
if (confirm('Neue Version verfügbar. Jetzt aktualisieren?')) {
worker.postMessage({ type: 'SKIP_WAITING' });
}
};
if (reg.waiting) promptUpdate(reg.waiting);
reg.addEventListener('updatefound', () => {
const newWorker = reg.installing;
newWorker.addEventListener('statechange', () => {
if (newWorker.state === 'installed' && navigator.serviceWorker.controller) {
promptUpdate(newWorker);
}
});
});
Seite nach dem Worker-Wechsel neu laden
// main.js – nach skipWaiting() wechselt der Controller
let reloading = false;
navigator.serviceWorker.addEventListener('controllerchange', () => {
if (reloading) return; // Endlosschleife verhindern
reloading = true;
console.log('Neuer Controller – lade neu');
window.location.reload();
});
// Wichtig · Fallstricke
- Versionskonflikte: Offene Tabs laufen nach dem Wechsel mit altem Code weiter, ihre Anfragen gehen aber schon an den neuen Worker. Wenn sich Cache-Namen, API-Routen oder Dateinamen ändern, kann das zu fehlerhaften Antworten führen. Lade die Seite deshalb über
controllerchangeneu oder frage den Nutzer vorher (siehe Beispiel 2). - Das zurückgegebene Promise wird sofort erfüllt. Ein
await self.skipWaiting()sagt also nichts darüber aus, ob die Aktivierung schon abgeschlossen ist. Code, der den aktiven Zustand braucht, gehört in dasactivate-Event. skipWaiting()allein übernimmt keine bereits offenen Seiten, die bisher von keinem Worker kontrolliert wurden. Dafür brauchst du zusätzlichclients.claim().- Die Methode gibt es nur im Service-Worker-Kontext. In der Seite heißt das Gegenstück
registration.waiting.postMessage(...), das eine Nachricht an den wartenden Worker schickt. - Service Worker laufen nur in sicheren Kontexten (HTTPS oder
localhost). In Firefox sind sie im privaten Modus je nach Version nicht verfügbar. - In den DevTools (Chrome: Application → Service Workers) kannst du mit „skipWaiting“ bzw. „Update on reload“ dasselbe Verhalten beim Entwickeln auslösen.