Start · Sprachen · JavaScript · Referenz · ServiceWorkerRegistration.waiting

ServiceWorkerRegistration.waiting

Eigenschaft

Schreibgeschützte Eigenschaft, die den installierten, aber noch nicht aktiven Service Worker (<code>state === "installed"</code>) einer Registrierung liefert – oder <code>null</code>.

seit JavaScript Baseline: alle modernen Browser (seit ca. 2018, Sa Kategorie: webapi

Signatur

ServiceWorkerRegistration.waiting

Beschreibung

Die Eigenschaft waiting eines ServiceWorkerRegistration-Objekts verweist auf einen Service Worker, der fertig installiert ist, aber noch wartet, bis er aktiviert werden darf. Sein state ist "installed". Gibt es keinen solchen Worker, ist der Wert null.

Ein neuer Service Worker bleibt standardmäßig so lange im Wartezustand, bis keine Seite (kein Client) mehr vom alten, aktiven Worker gesteuert wird. So laufen nie zwei Versionen gleichzeitig für dieselbe Seite. Erst wenn alle Tabs geschlossen sind oder der Worker self.skipWaiting() aufruft, wird er aktiv und erscheint unter registration.active.

In der Praxis nutzt man waiting vor allem für ein „Update verfügbar“-Banner: Die Seite erkennt eine wartende neue Version, fragt den Nutzer und schickt dem wartenden Worker per postMessage() den Befehl, skipWaiting() auszuführen. Danach lädt man die Seite neu, sobald das Ereignis controllerchange eintritt.

Zusammen mit installing und active bildet waiting die drei Lebenszyklus-Stufen, die eine Registrierung gleichzeitig halten kann.

Rückgabewert

Typ
ServiceWorker | null
Beschreibung
Der wartende ServiceWorker mit state === "installed" oder null, wenn aktuell kein Worker wartet.

Beispiele

Prüfen, ob eine neue Version wartet

const registration = await navigator.serviceWorker.getRegistration();

if (registration?.waiting) {
  console.log('Neue Version wartet:', registration.waiting.scriptURL);
  console.log('Status:', registration.waiting.state);
} else {
  console.log('Keine wartende Version.');
}
Neue Version wartet: https://example.com/sw.js Status: installed

„Update verfügbar“-Banner mit skipWaiting

// Seite (main.js)
const showUpdateBanner = (worker) => {
  if (confirm('Neue Version verfügbar. Jetzt aktualisieren?')) {
    worker.postMessage({ type: 'SKIP_WAITING' });
  }
};

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

// Fall 1: Beim Laden wartet bereits ein Worker
if (registration.waiting) {
  showUpdateBanner(registration.waiting);
}

// Fall 2: Ein Update wird während der Sitzung gefunden
registration.addEventListener('updatefound', () => {
  const newWorker = registration.installing;
  newWorker?.addEventListener('statechange', () => {
    // Nur als Update werten, wenn bereits ein Controller existiert
    if (newWorker.state === 'installed' && navigator.serviceWorker.controller) {
      showUpdateBanner(registration.waiting);
    }
  });
});

// Nach der Aktivierung einmalig neu laden
let reloaded = false;
navigator.serviceWorker.addEventListener('controllerchange', () => {
  if (reloaded) return;
  reloaded = true;
  window.location.reload();
});

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

Alle Lebenszyklus-Stufen einer Registrierung auflisten

const registrations = await navigator.serviceWorker.getRegistrations();

for (const reg of registrations) {
  console.table({
    scope: reg.scope,
    installing: reg.installing?.state ?? '–',
    waiting: reg.waiting?.state ?? '–',
    active: reg.active?.state ?? '–'
  });
}
scope: https://example.com/ | installing: – | waiting: installed | active: activated

// Wichtig · Fallstricke

  • Erstinstallation: Gibt es noch keinen aktiven Worker, bleibt der neue nicht in der Warteschlange, sondern wird sofort aktiviert. waiting ist dann meist null. Prüfen Sie deshalb navigator.serviceWorker.controller, damit Sie ein Update nicht mit der ersten Installation verwechseln.
  • Neuladen genügt nicht: Ein einfaches Neuladen (F5) aktiviert den wartenden Worker oft nicht, weil der alte Client während der Navigation weiterbesteht. Erst wenn alle Tabs geschlossen sind oder skipWaiting() aufgerufen wird, geht es weiter.
  • Vorsicht bei skipWaiting(): Offene Seiten können dann mit einem neuen Worker weiterlaufen, der Ressourcen einer anderen Version ausliefert. Deshalb nach controllerchange neu laden und einen Merker gegen Endlosschleifen setzen.
  • Der Wert ist nur eine Momentaufnahme. Wer auf Änderungen reagieren will, nutzt updatefound und statechange, statt die Eigenschaft wiederholt abzufragen.
  • Service Worker gibt es nur in sicheren Kontexten (HTTPS oder localhost). In privaten Fenstern mancher Browser, z. B. Firefox, ist navigator.serviceWorker eventuell nicht verfügbar.