Signatur
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
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`);
})()
);
});
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());
});
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`);
})());
});
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);
});
});
// Wichtig · Fallstricke
- Nur wenige Male ausgelöst:
installläuft pro Worker-Version genau einmal, nicht bei jedem Seitenaufruf. Eine neue Installation gibt es nur, wenn sichsw.jsbyteweise ändert. Importierte Skripte zählen je nachupdateViaCachemit. 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 einemawaitim Handler ist es dafür zu spät, dann wirft der Browser einenInvalidStateError.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. StattdessenCache,IndexedDBundfetchverwenden. - 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.