JavaScript/Objekte/ServiceWorkerGlobalScope
Die Schnittstelle ServiceWorkerGlobalScope ist ein Teil des Serviceworker-API. Sie stellt eine Erweiterung der WorkerGlobalScope-Schnittstelle dar und beinhaltet damit auch das WindowOrWorkerGlobalScope-Mixin.
Das globale Objekt eines Serviceworkers ist ein ServiceWorkerGlobalScope-Objekt.
self
und globalThis
. Ein window-Objekt gibt es in Workern nicht.Außer den von WorkerGlobalScope und WindowOrWorkerGlobalScope übernommenen Eigenschaften, Methoden und Ereignissen bietet die ServiceWorkerGlobalScope-Schnittstelle noch folgendes an:
Eigenschaften
Von WorkerGlobalScope geerbt:
Von WindowOrWorkerGlobalScope hinzugefügt:
Eigene:
- clients
- registration
- serviceWorker
Methoden
Von WorkerGlobalScope geerbt:
Von WindowOrWorkerGlobalScope hinzugefügt:
Eigene:
Ereignisse
Von WorkerGlobalScope geerbt:
Eigene:
Auf Ereignisse auf ServiceWorkerGlobalScope zu reagieren ist die Hauptaufgabe eines Serviceworkers.
Eigenschaften
- clients
- Kein Array, sondern ein Clients-Objekt, das Zugriff auf die aktiven Clients des Serviceworkers bietet.
- registration
- Enthält das ServiceWorkerRegistration-Objekt, das den in diesem Scope laufenden Serviceworker verwaltet.
- serviceWorker
- Enthält das ServiceWorker-Objekt, das in diesem Scope ausgeführt wird.
- Prüfen Sie vor der Verwendung, ob die Eigenschaft vorhanden ist, Firefox unterstützt sie zur Zeit noch nicht.
Methoden
skipWaiting()
Diese Methode kann von einer Serviceworker-Instanz verwendet werden, die in der Registration noch als waiting
eingetragen ist, um die active
-Instanz zu verdrängen und selbst zum aktiven ServiceWorker zu werden.
Die Clients der bisher aktiven ServiceWorker-Instanz werden von diesem Wechsel durch ein controllerchange
Event auf ihrem ServiceWorkerContainer-Objekt benachrichtigt. Überlegen Sie gut, ob Sie skipWaiting verwenden wollen. Der Austausch des aktiven ServiceWorkers kann zu kniffligen Problem führen, wenn Clients und Worker intensiv miteinander interagieren[1].
Ereignisse
An dieser Stelle werden die Ereignisse nur grundsätzlich dargestellt. Beispiele für eine Realisierung finden Sie im App-Tutorial.
Wenn ein Serviceworker-Script geladen und ausgeführt wird, tut es nicht viel mehr, als einige Variablen zu initialisieren und Handler für die im Folgenden beschriebenen Ereignisse zu registrieren. Die eigentliche Arbeit des Workers findet in den Eventhandler-Funktionen dieser Ereignisse statt.
Wichtige Hinweise
Alle Ereignisse, die auf dem ServiceWorkerGlobalScope ausgelöst werden, verwenden die Schnittstelle ExtendableEvent oder eine, die davon abgeleitet ist. Ein solches Ereignis ist nicht automatisch erledigt, wenn alle dafür registrierten Eventhandler-Funktionen enden, sondern es bleibt im Zustand active, bis alle in ihm registrierten Lifetime-Promises erfüllt wurden. Hinzu kommt, dass solche Events in dem Serviceworker gespeichert werden, für den sie ausgelöst wurden. Ein Serviceworker, der beendet werden soll, wartet damit so lange, bis er kein aktives ExtendableEvent mehr in seiner Liste hat. Bitte lesen Sie den Artikel zu ExtendableEvent für weitere Informationen.
install
Typ des Ereignisobjekts: ExtendableEvent
Wenn ein Serviceworker-Script erstmalig oder als neue Version geladen wird, bekommt es mit dem install
Event zunächst die Gelegenheit, sich zu initialisieren. Sobald dieses Event erfolgreich behandelt wurde, geht der initialisierte ServiceWorker in den waiting
Zustand über.
Das Event ist erfolgreich behandelt, wenn keines seiner Lifetime-Promises, die Sie mit der waitUntil()
-Methode registrieren können, mit einem Reject erfüllt wird. Es ist deshalb wichtig, dass Sie zurückgegebene Promises von asynchronen Methoden, die Sie im install-Eventhandler benötigen, mit waitUntil()
am Ereignisobjekt registrieren.
const myCacheName = 'Selfcache-V1';
const offlineFiles = [ 'index.html', 'style.css', 'app.js', 'background.png' ];
self.addEventListener("install", (installEvent) => {
installEvent.waitUntil(installHandler(installEvent));
});
function installHandler(installEvent) {
return caches
.open(myCacheName)
.then(cache => cache.addAll(offlineFiles))
}
Ein erfolgreich ausgeführtes Install-Event bringt den Serviceworker in den installed-Zustand. Im ServiceWorkerRegistration-Objekt findet er sich jetzt in der waiting
Eigenschaft.
activate
Typ des Ereignisobjekts: ExtendableEvent
Der Serviceworker erhält das activate
Event, sobald er zum aktiven ServiceWorker werden kann. Solange es für seine Registrierung noch keinen aktiven Serviceworker gibt, erfolgt das sofort nach dem install-Event. Andernfalls wartet der Browser mit dem activate-Event, bis der aktive Serviceworker keine Clients mehr hat, oder der wartende Serviceworker die Aktivierung mittels skipWaiting()
erzwingt.
Der activate-Eventhandler hat die Aufgabe, den Übergang zwischen Serviceworker-Versionen zu steuern. Dazu kann gehören: - den Cache der Offlinedateien neu zu laden - Daten, die von der vorherigen Version erstellt wurden, umzuspeichern - Daten, die die vorherige Version hinterlassen hat, zu entfernen
Die korrekte Datenübernahme bei Softwareupdates ist etwas, das man sehr genau planen muss. Es ist beispielsweise nicht gewährleistet, dass die Version 17 Ihres Serviceworkers die Version 16 ersetzt. Wenn der Computer zuvor länger nicht genutzt wurde, kann es durchaus geschehen, dass die Version 17 die erste Version überhaupt ist, oder auch dass sie die Version 1 ersetzt.
Genau wie im install-Event kann es auch im activate-Event nötig sein, Methoden aufzurufen, die Promises zurückliefern. Verwenden Sie auch hier die waitUntil-Methode des Eventobjekts, um den Abschluss der Aktivierung hinauszuzögern, bis diese Promises erfüllt sind.
Dass ein Serviceworker aktiv wurde, bedeutet nicht, dass er automatisch allen potenziellen Clients (Webseiten und Webworker) zugeordnet wird, die in seiner Scope-URL liegen. Von allein geschieht das nur für Clients, die nach der Aktivierung des Serviceworkers geladen wurden. Sie können aber auch die claim()-Methode des Clients-Objekt verwenden, um bereits geladene Clients an den Serviceworker zu binden. Genau wie bei skipWaiting()
erhalten die so angebundenen Clients ein controllerchanged
Event, um auf die Zuordnung des Serviceworkers reagieren zu können.
fetch
Typ des Ereignisobjekts: FetchEvent (abgeleitet von ExtendableEvent)
Sobald ein Client von einem Serviceworker kontrolliert wird, führt jedes Laden einer externen Ressource zu einem fetch-Event auf dem self-Objekt des Serviceworkers. Das fetchEvent-Objekt enthält den Request, der an den Server geschickt werden soll. Der Serviceworker kann daraufhin den Request aus dem Cache beantworten oder ihn mit Hilfe des fetch API an den Server weiterleiten. Beide Alternativen führen zu einem Promise, das zu einem Response-Objekt resolved wird, und das fetchEvent-Objekt stellt die Methode respondWith()
bereit, um auf die Erfüllung dieses Promises zu warten und das erhaltene Response-Objekt an den Client zurückzugeben.
respondWith()
verhält sich ähnlich wie waitUntil()
, sie fügt das übergebene Promise der Liste von Lifetime-Promises des Fetch-Events hinzu. Der Unterschied ist, dass der Wert des an respondWith()
übergebenen Promises zum Ergebnis des Fetch-Vorgangs beim Client wird. Aber beide haben gemeinsam, dass die Event-Behandlung erst abgeschlossen ist, wenn alle Lifetime-Promises erfüllt wurden. Weitere Lifetime-Promises können auch in einem fetch-Event sinnvoll sein: Wenn Sie zu einem Request keinen Eintrag im Cache finden, möchten Sie ihn vielleicht in den Cache legen, nachdem der Server die Response geliefert hat. Dieser Schreibvorgang in den Cache ist ebenfalls Promise-gesteuert, und Sie sollten dieses Promise mit waitUntil der Liste der Lifetime-Promises hinzufügen.
message
Typ des Ereignisobjekts: ExtendableMessageEvent (abgeleitet von ExtendableEvent)
Dieses Ereignis wird ausgelöst, wenn der ServiceWorker eine Nachricht von einem seiner Clients erhält. Der Client ruft postMessage() auf dem ServiceWorker-Objekt auf, ausgelöst wird das Ereignis aber auf dem ServiceWorkerGlobalScope-Objekt.
Ein ExtendableMessageEvent ist eine Mischung aus einem normalen MessageEvent und einem ExtendableEvent. Sie finden die übermittelten Daten wie gewohnt in der Eigenschaft data
, den Absender in source
und seinen Origin in origin
.
messageerror
Typ des Ereignisobjekts: ExtendableMessageEvent (abgeleitet von ExtendableEvent)
Dieses Ereignis signalisiert, dass dem Serviceworker eine Nachricht geschickt wurde, diese aber nicht deserialisiert werden konnte. Näheres finden Sie bei der Beschreibung von MessageEvent.
Referenzen
- ↑ Google Web Fundamentals: Serviceworkers Lifecycle
installHandler
gibt ein Promise zurück, das sich erfüllt, sobald der Cache befüllt ist.
Strukturen dieser Art sind für asynchrone Programmierschnittstellen, wie man sie in Workern oder auch in node.js findet, typisch.