Start · Sprachen · JavaScript · Referenz · ServiceWorkerGlobalScope

ServiceWorkerGlobalScope

Schnittstelle

Der globale Ausführungskontext eines Service Workers. Er wird über <code>self</code> angesprochen und stellt Lebenszyklus-, Fetch-, Push- und Nachrichten-Events bereit.

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

Signatur

interface ServiceWorkerGlobalScope extends WorkerGlobalScope

Beschreibung

ServiceWorkerGlobalScope ist das globale Objekt innerhalb eines Service-Worker-Skripts – dort, wo im Hauptthread window steht. Man greift darauf über self oder globalThis zu. Die Schnittstelle erbt von WorkerGlobalScope. Darüber sind unter anderem fetch(), caches, indexedDB, setTimeout() und importScripts() verfügbar. Einen Zugriff auf das DOM gibt es nicht.

Wichtige eigene Eigenschaften und Methoden:

  • self.clients – ein Clients-Objekt, mit dem man die gesteuerten Fenster und Tabs findet, anspricht oder neue Fenster öffnet.
  • self.registration – die zugehörige ServiceWorkerRegistration, z. B. für showNotification() oder pushManager.
  • self.serviceWorker – das eigene ServiceWorker-Objekt (neuer, noch nicht überall verfügbar).
  • self.skipWaiting() – aktiviert einen neu installierten Worker sofort, ohne dass er warten muss, bis alle alten Tabs geschlossen sind.

Die eigentliche Logik steckt in Event-Handlern: install, activate, fetch, message, push, notificationclick, sync sowie periodicsync. Die meisten davon sind ExtendableEvents. Mit event.waitUntil(promise) hält man den Worker am Leben, bis die asynchrone Arbeit abgeschlossen ist. Bei fetch liefert event.respondWith() eine eigene Antwort – das ist die Grundlage für Offline-Fähigkeit und Caching-Strategien.

Man verwendet diese Schnittstelle nur innerhalb der Service-Worker-Datei. Die Registrierung selbst passiert im Seitenkontext über navigator.serviceWorker.register().

Rückgabewert

Typ
ServiceWorkerGlobalScope
Beschreibung
Wird nicht selbst erzeugt, sondern vom Browser als globales Objekt self im Service Worker bereitgestellt.

Beispiele

Install: statische Ressourcen vorab cachen

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

self.addEventListener('install', (event) => {
  event.waitUntil(
    (async () => {
      const cache = await caches.open(CACHE);
      await cache.addAll(ASSETS);
      await self.skipWaiting(); // neue Version sofort aktivieren
      console.log('Assets gecacht');
    })()
  );
});
Assets gecacht

Activate: alte Caches löschen und Clients übernehmen

self.addEventListener('activate', (event) => {
  event.waitUntil(
    (async () => {
      const keys = await caches.keys();
      await Promise.all(
        keys.filter((k) => k !== 'app-v2').map((k) => caches.delete(k))
      );
      await self.clients.claim(); // offene Seiten sofort steuern
    })()
  );
});

Fetch: Cache-first mit Netzwerk-Fallback

self.addEventListener('fetch', (event) => {
  if (event.request.method !== 'GET') return;

  event.respondWith(
    (async () => {
      const cached = await caches.match(event.request);
      if (cached) return cached;
      try {
        const response = await fetch(event.request);
        const cache = await caches.open('app-v2');
        cache.put(event.request, response.clone());
        return response;
      } catch {
        return new Response('Offline', { status: 503 });
      }
    })()
  );
});

Nachrichten an alle Tabs senden und Push anzeigen

self.addEventListener('message', async (event) => {
  if (event.data?.type === 'PING') {
    const all = await self.clients.matchAll({ type: 'window' });
    all.forEach((client) => client.postMessage({ type: 'PONG', count: all.length }));
  }
});

self.addEventListener('push', (event) => {
  const data = event.data?.json() ?? { title: 'Neuigkeit' };
  event.waitUntil(
    self.registration.showNotification(data.title, { body: data.body })
  );
});
// Im Tab: { type: 'PONG', count: 2 }

// Wichtig · Fallstricke

  • Nur über HTTPS (bzw. über localhost): Service Worker laufen ausschließlich in sicheren Kontexten.
  • Kein dauerhafter Zustand: Der Browser beendet einen untätigen Worker jederzeit. Globale Variablen gehen dabei verloren. Dauerhafte Daten gehören in caches oder indexedDB.
  • waitUntil()/respondWith() synchron aufrufen: Sie müssen noch im selben Durchlauf des Event-Handlers aufgerufen werden, nicht erst nach einem await. Sonst wirft der Aufruf einen InvalidStateError.
  • Keine synchronen APIs: localStorage, XMLHttpRequest und DOM-Zugriffe stehen nicht zur Verfügung. importScripts() funktioniert nur während der Installation. Bei Modul-Workern (type: 'module') wird stattdessen import verwendet.
  • skipWaiting() mit Vorsicht: Bereits geöffnete Seiten können dann mit Assets aus einer anderen Version laufen. Ohne passende Versionierung der Caches führt das zu inkonsistenten Zuständen.
  • Scope: Ein Worker steuert nur Seiten unterhalb seines Pfads, es sei denn, der Header Service-Worker-Allowed erlaubt mehr.
  • Die Events sync und periodicsync gibt es in Firefox und Safari nicht. self.serviceWorker ist erst in neueren Browsern verfügbar.