Start · Sprachen · JavaScript · Referenz · ServiceWorkerGlobalScope: install

ServiceWorkerGlobalScope: install

Ereignis

Wird im Service Worker ausgelöst, sobald eine Registrierung einen neuen <code>installing</code>-Worker erhält. Hier legt man typischerweise den Offline-Cache an.

seit JavaScript Baseline: alle modernen Browser (seit 2018) Kategorie: webapi

Signatur

self.addEventListener("install", (event) => { … })

Beschreibung

Das install-Ereignis ist das erste Lebenszyklus-Ereignis, das ein Service Worker im eigenen globalen Gültigkeitsbereich (ServiceWorkerGlobalScope) erhält. Es wird ausgelöst, wenn ServiceWorkerRegistration.installing einen neuen Worker bekommt. Das passiert bei der ersten Registrierung und bei jeder Aktualisierung, bei der sich das Skript byteweise geändert hat.

Der Handler bekommt ein ExtendableEvent. Mit event.waitUntil(promise) lässt sich die Installation verlängern, bis ein Promise erfüllt ist, zum Beispiel bis alle statischen Ressourcen (App-Shell) mit caches.open() und cache.addAll() vorab zwischengespeichert sind. Wird das Promise abgelehnt, schlägt die Installation fehl: Der neue Worker wird verworfen und ein eventuell schon laufender Worker bleibt aktiv.

Nach einer erfolgreichen Installation wechselt der Worker in den Zustand installed (waiting). Aktiv wird er erst, wenn keine Clients mehr vom alten Worker gesteuert werden, oder sofort, wenn man self.skipWaiting() aufruft. Aufräumarbeiten wie das Löschen alter Caches gehören in das anschließende activate-Ereignis und nicht in install.

Einen Handler registriert man entweder mit self.addEventListener("install", handler) oder über die Eigenschaft self.oninstall = handler. Mit addEventListener sind mehrere Handler möglich, mit oninstall nur einer.

Parameter

Name Typ Default Beschreibung
$type Pflicht string Der Ereignisname "install".
$listener Pflicht (event: ExtendableEvent) => void Callback, der ein ExtendableEvent erhält. Mit event.waitUntil(promise) verlängert er die Installationsphase.
$options boolean | AddEventListenerOptions false Optionale Listener-Optionen wie once oder signal.

Rückgabewert

Typ
void
Beschreibung
addEventListener gibt nichts zurück. Den Ausgang der Installation steuert das Promise, das an event.waitUntil() übergeben wird.

Beispiele

App-Shell beim Installieren vorab zwischenspeichern

// sw.js
const CACHE_NAME = 'app-shell-v2';
const ASSETS = ['/', '/index.html', '/styles.css', '/app.js', '/offline.html'];

self.addEventListener('install', (event) => {
  event.waitUntil(
    (async () => {
      const cache = await caches.open(CACHE_NAME);
      await cache.addAll(ASSETS); // schlägt ein Request fehl, scheitert die Installation
      console.log(`[SW] ${ASSETS.length} Dateien in ${CACHE_NAME} gespeichert`);
    })()
  );
});
[SW] 5 Dateien in app-shell-v2 gespeichert

Sofort aktivieren mit skipWaiting() über oninstall

// sw.js – die Eigenschaft oninstall statt addEventListener
self.oninstall = (event) => {
  console.log('[SW] Neue Version wird installiert');
  // Wartephase überspringen: der neue Worker wird direkt aktiv
  event.waitUntil(self.skipWaiting());
};

self.addEventListener('activate', (event) => {
  // Bereits geöffnete Seiten sofort übernehmen
  event.waitUntil(self.clients.claim());
});
[SW] Neue Version wird installiert

Optionale Ressourcen, ohne dass die Installation scheitert

// sw.js
self.addEventListener('install', (event) => {
  event.waitUntil((async () => {
    const cache = await caches.open('static-v1');
    // Pflicht-Ressourcen: ein Fehler bricht die Installation ab
    await cache.addAll(['/index.html', '/app.js']);
    // Optionale Ressourcen: Fehler werden nur protokolliert
    const optional = ['/img/hero.webp', '/fonts/inter.woff2'];
    const results = await Promise.allSettled(optional.map((url) => cache.add(url)));
    const failed = results.filter((r) => r.status === 'rejected').length;
    console.log(`[SW] Optionale Dateien: ${optional.length - failed} ok, ${failed} fehlgeschlagen`);
  })());
});
[SW] Optionale Dateien: 2 ok, 0 fehlgeschlagen

Installationsfortschritt auf der Seite beobachten

// main.js (Seite, nicht Service Worker)
const registration = await navigator.serviceWorker.register('/sw.js');
registration.addEventListener('updatefound', () => {
  const worker = registration.installing;
  worker.addEventListener('statechange', () => {
    console.log('Worker-Status:', worker.state);
  });
});
Worker-Status: installed Worker-Status: activating Worker-Status: activated

// Wichtig · Fallstricke

  • Nur wenige Male ausgelöst: install läuft pro Worker-Version genau einmal, nicht bei jedem Seitenaufruf. Eine neue Installation gibt es nur, wenn sich sw.js byteweise ändert. Importierte Skripte zählen je nach updateViaCache mit. Eine neue Version bei geänderten Dateien erzwingt man deshalb, indem man den Cache-Namen hochzählt.
  • waitUntil() nur synchron aufrufen: Der Aufruf muss direkt im Handler stehen. Nach einem await im Handler ist es dafür zu spät, dann wirft der Browser einen InvalidStateError.
  • cache.addAll() ist atomar: Scheitert eine einzige URL (404, Netzwerkfehler), wird das ganze Promise abgelehnt und die Installation schlägt fehl. Bei großen oder unsicheren Listen deshalb zwischen Pflicht- und optionalen Ressourcen trennen.
  • skipWaiting() mit Vorsicht: Offene Seiten laufen dann unter Umständen mit altem HTML/JS gegen den neuen Worker und neue Cache-Inhalte. Das kann zu schwer auffindbaren Versionskonflikten führen.
  • Kein Zugriff auf das DOM und keine synchronen APIs wie localStorage. Stattdessen Cache, IndexedDB und fetch verwenden.
  • Kompatibilität und Sicherheit: Service Worker gibt es nur in sicheren Kontexten (HTTPS oder localhost). Unterstützt werden sie in allen modernen Browsern (Chrome 40+, Firefox 44+, Safari 11.1+, Edge 17+). Im privaten Modus mancher Browser (z. B. älteres Firefox) sind sie nicht verfügbar.