Dieses Codelab ist Teil des Schulungsprogramms „Progressive Web-Apps entwickeln“, die vom Google Developers-Schulungsteam entwickelt wurden. Dieser Kurs eignet sich am besten für Sie, wenn Sie nacheinander die Codelabs durcharbeiten.
Umfassende Informationen zum Kurs finden Sie unter Progressive Web-Apps entwickeln.
Einführung
In diesem Lab erfahren Sie, wie Sie einen einfachen Service Worker erstellen.
Lerninhalte
- Grundlegendes Service Worker-Skript erstellen, installieren und einfache Fehlerbehebung ausführen
Wichtige Informationen
- Grundlegendes JavaScript und HTML
- Konzepte und grundlegende Syntax von ES2015-Promise
- Entwicklerkonsole aktivieren
Voraussetzungen
- Computer mit Terminal-/Shell-Zugriff
- Verbindung zum Internet
- Ein Browser, der Service Worker unterstützt
- Ein Texteditor
Laden Sie das pwa-training-labs-Repository aus GitHub herunter oder klonen Sie es. Installieren Sie gegebenenfalls die LTS-Version von Node.js.
Rufen Sie das Verzeichnis service-worker-lab/app/
auf und starten Sie einen lokalen Entwicklungsserver:
cd service-worker-lab/app npm install node server.js
Sie können den Server jederzeit mit Ctrl-c
beenden.
Öffnen Sie Ihren Browser und rufen Sie localhost:8081/
auf.
Hinweis: Heben Sie die Registrierung von Service Workern auf und löschen Sie alle Caches des Service Worker für localhost, damit sie das Lab nicht beeinträchtigen. In den Chrome-Entwicklertools können Sie das tun, indem Sie auf dem Tab Anwendung im Abschnitt Speicherinhalt löschen auf Websitedaten löschen klicken.
Öffne den Ordner service-worker-lab/app/
in deinem bevorzugten Texteditor. In diesem Ordner erstellen Sie das Lab app/
.
In diesem Ordner finden Sie Folgendes:
below/another.html
,js/another.js
,js/other.js
undother.html
sind Beispielressourcen, die wir zum Testen des Service Worker-Bereichs verwenden- Der Ordner
styles/
enthält die kaskadierenden Stylesheets für dieses Lab - Der Ordner „
test/
“ enthält Dateien zum Testen Ihres Fortschritts index.html
ist die Haupt-HTML-Seite für unsere Beispielwebsite/-anwendungservice-worker.js
ist die JavaScript-Datei, die zum Erstellen des Service Workers verwendet wirdpackage.json
undpackage-lock.json
verfolgen die in diesem Projekt verwendeten Knotenpaketeserver.js
ist ein einfacher Express-Server, über den wir unsere App hosten
Öffne service-worker.js
in deinem Texteditor. Hinweis: Die Datei ist leer. Wir haben noch keinen Code für die Ausführung im Service Worker hinzugefügt.
Öffne index.html
in deinem Texteditor.
Fügen Sie in den <script>
-Tags den folgenden Code ein, um den Service Worker zu registrieren:
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('service-worker.js')
.then(registration => {
console.log('Service Worker is registered', registration);
})
.catch(err => {
console.error('Registration failed:', err);
});
});
}
Speichern Sie das Skript und aktualisieren Sie die Seite. In der Konsole sollte die Nachricht angezeigt werden, dass der Service Worker registriert wurde. Sie können in Chrome prüfen, ob ein Service Worker registriert ist. Öffnen Sie dazu die Entwicklertools (Strg + Umschalttaste + I unter Windows und Linux oder ⌘ + Alt + I auf dem Mac), klicken Sie auf den Tab Anwendung und dann auf die Option Service Worker. Die Ausgabe sollte in etwa so aussehen:
Optional: Öffnen Sie die Website in einem nicht unterstützten Browser und prüfen Sie, ob die Bedingung der Supportprüfung funktioniert.
Erklärung
Mit dem obigen Code wird die Datei service-worker.js
als Service Worker registriert. Er prüft zuerst, ob der Browser Service Worker unterstützt. Dies sollte jedes Mal durchgeführt werden, wenn Sie einen Service Worker registrieren, da einige Browser diese möglicherweise nicht unterstützen. Der Code registriert dann den Service Worker mit der register
-Methode der ServiceWorkerContainer
API, die in der Navigator
-Schnittstelle des Fensters enthalten ist.
navigator.serviceWorker.register(...)
gibt ein Promise zurück, das mit einem registration
-Objekt aufgelöst wird, sobald der Service Worker registriert wurde. Wenn die Registrierung fehlschlägt, wird das Versprechen abgelehnt.
Statusänderungen durch den Service Worker lösen Ereignisse im Service Worker aus.
Ereignis-Listener hinzufügen
Öffne service-worker.js
in deinem Texteditor.
Fügen Sie dem Service Worker die folgenden Ereignis-Listener hinzu:
self.addEventListener('install', event => {
console.log('Service worker installing...');
// Add a call to skipWaiting here
});
self.addEventListener('activate', event => {
console.log('Service worker activating...');
});
Speichern Sie die Datei.
Heben Sie die Registrierung des Service Workers manuell auf und aktualisieren Sie die Seite, um den aktualisierten Service Worker zu installieren und zu aktivieren. Im Konsolenprotokoll sollte angezeigt werden, dass der neue Service Worker registriert, installiert und aktiviert wurde.
Hinweis: Das Registrierungsprotokoll ist möglicherweise mit den anderen Protokollen (Installation und Aktivierung) falsch angeordnet. Der Service Worker wird gleichzeitig mit der Seite ausgeführt. Deshalb können wir die Reihenfolge der Logs nicht garantieren. Das Registrierungsprotokoll stammt von der Seite, die Installations- und Aktivierungsprotokolle stammen vom Service Worker. Die Installationen, Aktivierungen und anderen Service Worker-Ereignisse erfolgen jedoch in einer festgelegten Reihenfolge innerhalb des Service Workers und sollten immer in der erwarteten Reihenfolge auftreten.
Erklärung
Der Service Worker gibt am Ende der Registrierung ein install
-Ereignis aus. Im obigen Code wird eine Nachricht im Ereignis-Listener install
protokolliert. In einer echten Anwendung ist dies jedoch ein guter Ort zum Speichern von statischen Assets.
Wenn ein Service Worker registriert ist, erkennt der Browser, ob der Service Worker neu ist – entweder weil er sich vom zuvor installierten Service Worker unterscheidet oder weil für diese Website kein registrierter Service Worker vorhanden ist. Wenn der Service Worker neu ist (in diesem Fall), wird er vom Browser installiert.
Der Service Worker gibt ein activate
-Ereignis aus, wenn es die Kontrolle über die Seite übernimmt. Mit dem Code oben wird eine Nachricht protokolliert. Dieses Ereignis wird aber häufig zur Aktualisierung von Caches verwendet.
Es kann immer nur ein Service Worker für einen bestimmten Bereich aktiv sein (siehe „Dienst-Worker-Bereich erkunden“). Ein neu installierter Service Worker wird erst aktiviert, wenn der vorhandene Service Worker nicht mehr verwendet wird. Aus diesem Grund müssen alle Seiten, die von einem Service Worker kontrolliert werden, geschlossen werden, bevor ein neuer Service Worker die übernehmen kann. Da wir die Registrierung des bestehenden Service Workers aufgehoben haben, wurde der neue Service Worker sofort aktiviert.
Hinweis: Die Aktualisierung der Seite reicht nicht aus, um die Kontrolle an einen neuen Service Worker zu übertragen, da die neue Seite vor dem Entladen der aktuellen Seite angefordert wird und der alte Service Worker nicht verwendet wird.
Hinweis:Sie können einen neuen Service Worker auch manuell mit bestimmten Browsern und dem Entwicklertools mit skipWaiting()
aktivieren. Weitere Informationen finden Sie im Abschnitt 3.4.
Service Worker aktualisieren
Fügen Sie den folgenden Kommentar an einer beliebigen Stelle in service-worker.js
hinzu:
// I'm a new service worker
Speichern Sie die Datei und aktualisieren Sie die Seite. Sehen Sie sich die Logs in der Konsole an. Der neue Service Worker wird installiert, aber nicht aktiviert. In Chrome wird der Warte-Worker in den Entwicklertools auf dem Tab Application (Anwendung) angezeigt.
Schließen Sie alle mit dem Service Worker verknüpften Seiten. Öffnen Sie dann localhost:8081/
noch einmal. Im Konsolenprotokoll sollte angezeigt werden, dass der neue Service Worker jetzt aktiviert ist.
Hinweis: Falls Sie unerwartete Ergebnisse erhalten, deaktivieren Sie den HTTP-Cache in den Entwicklertools.
Erklärung
Im Browser wird aufgrund des hinzugefügten Kommentars ein Byteunterschied zwischen der neuen und der vorhandenen Service Worker-Datei erkannt. Dadurch wird der neue Service Worker installiert. Da immer nur ein Service Worker für einen bestimmten Bereich aktiv sein kann, wird der neue Service Worker erst dann aktiviert, wenn er nicht mehr verwendet wird. Durch das Schließen aller Seiten durch den alten Service Worker können wir den neuen Service Worker aktivieren.
Wartezeit warten
Ein neuer Service Worker kann sofort aktiviert werden, auch wenn ein vorhandener Service Worker vorhanden ist. Dazu wird die Wartezeit übersprungen.
Fügen Sie in service-worker.js
einen Aufruf für skipWaiting
im Ereignis-Listener install
hinzu:
self.skipWaiting();
Speichern Sie die Datei und aktualisieren Sie die Seite. Der neue Service Worker wird sofort installiert und aktiviert, auch wenn ein früherer Service Worker die Kontrolle hatte.
Erklärung
Mit der Methode skipWaiting()
kann ein Service Worker aktiviert werden, sobald die Installation abgeschlossen ist. Der Listener für Installationsereignisse ist ein gängiger Ort zum Starten des skipWaiting()
-Aufrufs. Er kann aber während oder vor der Wartezeit aufgerufen werden. In dieser Dokumentation finden Sie weitere Informationen zur Verwendung von skipWaiting()
. Für den Rest des Labs können Sie neuen Service Worker-Code testen, ohne die Registrierung des Service Workers manuell aufzuheben.
Weitere Informationen
Service Worker können als Proxy zwischen Ihrer Webanwendung und dem Netzwerk fungieren.
Fügen Sie einen Abruf-Listener hinzu, um Anfragen aus unserer Domain abzufangen.
Fügen Sie service-worker.js
den folgenden Code hinzu:
self.addEventListener('fetch', event => {
console.log('Fetching:', event.request.url);
});
Speichern Sie das Skript und aktualisieren Sie die Seite, um den aktualisierten Service Worker zu installieren und zu aktivieren.
Prüfen Sie die Konsole und stellen Sie fest, dass keine Abrufereignisse protokolliert wurden. Aktualisieren Sie die Seite und prüfen Sie die Konsole noch einmal. Sie sollten dieses Mal die Abrufereignisse für die Seite und ihre Assets sehen, etwa CSS.
Klicken Sie auf die Links Andere Seite, Eine andere Seite und Zurück.
Für jede der Seiten und ihre Assets werden die Abrufereignisse in der Konsole angezeigt. Sind alle Logs sinnvoll?
Hinweis: Wenn Sie eine Seite aufrufen und der HTTP-Cache nicht deaktiviert ist, werden CSS- und JavaScript-Assets möglicherweise lokal im Cache gespeichert. In diesem Fall werden keine Abrufereignisse für diese Ressourcen angezeigt.
Erklärung
Der Service Worker empfängt ein Abrufereignis für jede HTTP-Anfrage des Browsers innerhalb seines Bereichs. Das fetch event-Objekt enthält die Anfrage. Das Erfassen von Abrufereignissen im Service Worker ähnelt der Überwachung von Klickereignissen im DOM. In unserem Code protokollieren wir bei einem Abruf-Ereignis die angeforderte URL in der Konsole. In der Praxis können wir auch unsere eigene benutzerdefinierte Antwort mit willkürlichen Ressourcen erstellen und zurückgeben.
Warum wurden bei der ersten Aktualisierung keine Abruf-Ereignisprotokolle aufgezeichnet? Standardmäßig werden Ereignisse von einer Seite nicht durch einen Service Worker abgerufen, es sei denn, die Seitenanfrage selbst wurde von einem Service Worker verarbeitet. Dadurch wird die Konsistenz Ihrer Website gewährleistet. Wenn eine Seite ohne den Service Worker geladen wird, sollten Sie auch die zugehörigen Unterressourcen verwenden.
Weitere Informationen
Lösungscode
Wenn Sie eine Kopie des funktionierenden Codes abrufen möchten, gehen Sie zum Ordner 04-intercepting-network-requests/
.
Service Worker haben einen Umfang. Der Bereich des Service Workers bestimmt, von welchen Pfaden der Service Worker Anfragen abfängt.
Bereich finden
Aktualisieren Sie den Registrierungscode in index.html
mit:
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('service-worker.js')
.then(registration => {
console.log('SW registered with scope:', registration.scope);
})
.catch(err => {
console.error('Registration failed:', err);
});
});
}
Aktualisieren Sie die Browserseite. Die Konsole zeigt den Bereich des Service Workers an (in diesem Fall http://localhost:8081/
).
Erklärung
Das von register()
zurückgegebene Versprechen wird in das Registrierungsobjekt aufgelöst, das den Umfang des Service Workers enthält.
Der Standardumfang ist der Pfad zur Service Worker-Datei. Er erstreckt sich auf alle untergeordneten Verzeichnisse. Ein Service Worker im Stammverzeichnis einer App steuert also alle Anfragen von allen Dateien in der App.
Service Worker verschieben
Verschieben Sie service-worker.js
in das below/
-Verzeichnis und aktualisieren Sie die Service Worker-URL im Registrierungscode in index.html
.
Heben Sie die Registrierung des aktuellen Service Workers im Browser auf und aktualisieren Sie die Seite.
In der Konsole wird angezeigt, dass der Umfang des Service Workers jetzt http://localhost:8081/below/
ist. In Chrome können Sie den Bereich „Service Worker“ auch auf dem Tab „Anwendung“ der Entwicklertools sehen:
Klicken Sie auf der Hauptseite auf Andere Seite, Eine andere Seite und Zurück. Welche Abrufanfragen werden protokolliert? Welche sind?
Erklärung
Der Standardumfang des Service Workers ist der Pfad zur Service Worker-Datei. Da sich die Service Worker-Datei jetzt in below/
befindet, ist dieser Bereich. Die Konsole erfasst jetzt nur Abrufereignisse für another.html
, another.css
und another.js
, weil sie die einzigen Ressourcen innerhalb des Bereichs des Service Workers sind.
Beliebigen Bereich festlegen
Verschieben Sie den Service Worker wieder in das Projektstammverzeichnis (app/
) und aktualisieren Sie die Service Worker-URL im Registrierungscode in index.html
.
Legen Sie mithilfe der Referenz zu MDN den Bereich des Service Workers auf das Verzeichnis below/
fest. Verwenden Sie dazu den optionalen Parameter in register()
.
Heben Sie die Registrierung des Service Workers auf und aktualisieren Sie die Seite. Klicken Sie auf Andere Seite, Eine andere Seite und Zurück.
Auch hier zeigt die Konsole, dass der Bereich des Service Workers jetzt http://localhost:8081/below/
ist. Logs rufen nur Ereignisse für another.html
, another.css
und another.js
ab.
Erklärung
Sie können einen beliebigen Bereich festlegen, indem Sie bei der Registrierung einen zusätzlichen Parameter übergeben. Beispiel:
navigator.serviceWorker.register('/service-worker.js', {
scope: '/kitten/'
});
Im obigen Beispiel ist der Bereich des Service Workers auf /kitten/
festgelegt. Der Service Worker fängt Anfragen von Seiten in /kitten/
und /kitten/lower/
ab, aber nicht von Seiten wie /kitten
oder /
.
Hinweis:Sie können keinen beliebigen Bereich festlegen, der über dem tatsächlichen Standort des Service Workers liegt. Wenn Ihr Server-Worker jedoch auf einem Client aktiv ist, der mit dem Header Service-Worker-Allowed
bereitgestellt wird, können Sie einen maximalen Bereich für diesen Service-Worker über dem Standort des Service Workers angeben.
Weitere Informationen
Lösungscode
Wenn Sie eine Kopie des funktionierenden Codes abrufen möchten, gehen Sie zum Ordner solution/
.
Sie haben jetzt einen einfachen Service Worker und können den Lebenszyklus des Service Workers nachvollziehen.
Weitere Informationen
Alle Codelabs im Kurs "PWA-Schulung" finden Sie im Begrüßungs-Codelab.