In diesem Codelab erfahren Sie, wie Sie mit Workbox eine zuverlässige Suche implementieren. Die verwendete Demo-App enthält ein Suchfeld, das einen Serverendpunkt aufruft und den Nutzer zu einer einfachen HTML-Seite weiterleitet.
Messen
Bevor Sie Optimierungen vornehmen, sollten Sie immer zuerst den aktuellen Zustand der Anwendung analysieren.
- Klicke auf Remix zum Bearbeiten, um das Projekt bearbeitbar zu machen.
- Wenn Sie sich eine Vorschau der Website ansehen möchten, drücken Sie App ansehen und dann Vollbild .
Prüfen Sie in dem gerade geöffneten neuen Tab, wie sich die Website verhält, wenn Sie offline gehen:
- Drücken Sie „Strg + Umschalttaste + J“ (oder „Befehlstaste + Optionstaste + J“ auf einem Mac), um die Entwicklertools zu öffnen.
- Klicken Sie auf den Tab Netzwerk.
- Öffnen Sie die Chrome-Entwicklertools und wählen Sie den Bereich „Netzwerk“ aus.
- Wählen Sie in der Drop-down-Liste „Throttling“ die Option Offline aus.
- Geben Sie in der Demo-App eine Suchanfrage ein und klicken Sie auf die Schaltfläche Suchen.
Die Standard-Browserfehlerseite wird angezeigt:
Fallback-Antwort bereitstellen
Der Dienst-Worker enthält den Code, mit dem die Offlineseite der Liste für den Pre-Cache hinzugefügt wird, damit sie immer beim Dienst-Worker-Ereignis install
im Cache gespeichert werden kann.
Normalerweise müssen Sie Workbox anweisen, diese Datei zur Pre-Cache-Liste hinzuzufügen, indem Sie die Bibliothek in Ihr bevorzugtes Build-Tool einbinden (z.B. webpack oder gulp).
Der Einfachheit halber haben wir das bereits für Sie erledigt. Das geschieht mit dem folgenden Code bei public/sw.js
:
const FALLBACK_HTML_URL = '/index_offline.html';
…
workbox.precaching.precacheAndRoute([FALLBACK_HTML_URL]);
Fügen Sie als Nächstes Code hinzu, um die Offlineseite als Fallback-Antwort zu verwenden:
- Wenn Sie die Quelle aufrufen möchten, drücken Sie die Taste Quellcode ansehen.
- Fügen Sie den folgenden Code am Ende von
public/sw.js
ein:
workbox.routing.setDefaultHandler(new workbox.strategies.NetworkOnly());
workbox.routing.setCatchHandler(({event}) => {
switch (event.request.destination) {
case 'document':
return caches.match(FALLBACK_HTML_URL);
break;
default:
return Response.error();
}
});
Der Code führt Folgendes aus:
- Hiermit wird eine Standardstrategie vom Typ Nur Netzwerk definiert, die auf alle Anfragen angewendet wird.
- Deklariert einen globalen Fehlerhandler, indem
workbox.routing.setCatchHandler()
aufgerufen wird, um fehlgeschlagene Anfragen zu verwalten. Bei Anfragen für Dokumente wird eine Fallback-Offline-HTML-Seite zurückgegeben.
So testen Sie diese Funktion:
- Kehren Sie zum anderen Tab zurück, auf dem Ihre App ausgeführt wird.
- Stellen Sie in der Drop-down-Liste Drosselung wieder Online ein.
- Drücken Sie die Schaltfläche Zurück in Chrome, um zur Suchseite zurückzukehren.
- Das Kästchen Cache deaktivieren in den Entwicklertools muss deaktiviert sein.
- Halten Sie die Schaltfläche Aktualisieren in Chrome gedrückt und wählen Sie Cache leeren und hart neu laden aus, damit Ihr Service Worker aktualisiert wird.
- Stellen Sie in der Drop-down-Liste Throttling (Drosselung) wieder Offline ein.
- Geben Sie eine Suchanfrage ein und klicken Sie noch einmal auf die Schaltfläche Suchen.
Die Fallback-HTML-Seite wird angezeigt:
Berechtigung zum Senden von Benachrichtigungen anfordern
Der Code zum Anfordern von Berechtigungen für Benachrichtigungen ist bereits in der Offlineseite unter views/index_offline.html
in einem Scriptblock unten enthalten:
function requestNotificationPermission(event) {
event.preventDefault();
Notification.requestPermission().then(function (result) {
showOfflineText(result);
});
}
Der Code führt Folgendes aus:
- Wenn der Nutzer auf Benachrichtigungen abonnieren klickt, wird die Funktion
requestNotificationPermission()
aufgerufen, dieNotification.requestPermission()
aufruft, um die Standardaufforderung zur Browserberechtigung anzuzeigen. Das Versprechen wird mit der vom Nutzer ausgewählten Berechtigung aufgelöst. Das kann entwedergranted
,denied
oderdefault
sein. - Übergibt die ermittelte Berechtigung an
showOfflineText()
, um dem Nutzer den entsprechenden Text anzuzeigen.
Offlineabfragen beibehalten und noch einmal versuchen, wenn Sie wieder online sind
Implementieren Sie als Nächstes die Workbox-Hintergrundsynchronisierung, um Offlineabfragen zu speichern, damit sie wiederholt werden können, wenn der Browser erkennt, dass die Verbindung wiederhergestellt wurde.
- Öffnen Sie
public/sw.js
zum Bearbeiten. - Fügen Sie am Ende der Datei den folgenden Code ein:
const bgSyncPlugin = new workbox.backgroundSync.Plugin('offlineQueryQueue', {
maxRetentionTime: 60,
onSync: async ({queue}) => {
let entry;
while ((entry = await queue.shiftRequest())) {
try {
const response = await fetch(entry.request);
const cache = await caches.open('offline-search-responses');
const offlineUrl = `${entry.request.url}¬ification=true`;
cache.put(offlineUrl, response);
showNotification(offlineUrl);
} catch (error) {
await this.unshiftRequest(entry);
throw error;
}
}
},
});
Der Code führt Folgendes aus:
workbox.backgroundSync.Plugin
enthält die Logik, mit der fehlgeschlagene Anfragen einer Warteschlange hinzugefügt werden, damit sie später noch einmal versucht werden können. Diese Anfragen werden in IndexedDB gespeichert.maxRetentionTime
gibt an, wie lange eine Anfrage wiederholt werden kann. In diesem Fall haben wir 60 Minuten ausgewählt (nach denen die Daten verworfen werden).onSync
ist der wichtigste Teil dieses Codes. Dieser Rückruf wird aufgerufen, wenn die Verbindung wiederhergestellt wurde, damit die anstehenden Anfragen abgerufen und dann aus dem Netzwerk abgerufen werden.- Die Netzwerkantwort wird dem
offline-search-responses
-Cache hinzugefügt und die Abfrageparameter¬ification=true
werden angehängt, damit dieser Cacheeintrag abgerufen werden kann, wenn ein Nutzer auf die Benachrichtigung klickt.
Wenn Sie die Hintergrundsynchronisierung in Ihren Dienst einbinden möchten, definieren Sie eine NetworkOnly-Strategie für Anfragen an die Such-URL (/search_action
) und geben Sie die zuvor definierte bgSyncPlugin
weiter. Fügen Sie den folgenden Code am Ende von public/sw.js
ein:
const matchSearchUrl = ({url}) => {
const notificationParam = url.searchParams.get('notification');
return url.pathname === '/search_action' && !(notificationParam === 'true');
};
workbox.routing.registerRoute(
matchSearchUrl,
new workbox.strategies.NetworkOnly({
plugins: [bgSyncPlugin],
}),
);
Dadurch wird Workbox angewiesen, immer das Netzwerk aufzurufen und bei fehlgeschlagenen Anfragen die Hintergrundsynchronisierungslogik zu verwenden.
Fügen Sie als Nächstes unten in public/sw.js
den folgenden Code hinzu, um eine Caching-Strategie für Anfragen zu definieren, die von Benachrichtigungen stammen. Verwenden Sie die Strategie CacheFirst, damit sie aus dem Cache bereitgestellt werden können.
const matchNotificationUrl = ({url}) => {
const notificationParam = url.searchParams.get('notification');
return (url.pathname === '/search_action' && (notificationParam === 'true'));
};
workbox.routing.registerRoute(matchNotificationUrl,
new workbox.strategies.CacheFirst({
cacheName: 'offline-search-responses',
})
);
Fügen Sie abschließend den Code hinzu, um Benachrichtigungen anzuzeigen:
function showNotification(notificationUrl) {
if (Notification.permission) {
self.registration.showNotification('Your search is ready!', {
body: 'Click to see you search result',
icon: '/img/workbox.jpg',
data: {
url: notificationUrl
}
});
}
}
self.addEventListener('notificationclick', function(event) {
event.notification.close();
event.waitUntil(
clients.openWindow(event.notification.data.url)
);
});
Funktion testen
- Kehren Sie zum anderen Tab zurück, auf dem Ihre App ausgeführt wird.
- Stellen Sie in der Drop-down-Liste Drosselung wieder Online ein.
- Drücken Sie die Schaltfläche Zurück in Chrome, um zur Suchseite zurückzukehren.
- Halten Sie die Schaltfläche Aktualisieren in Chrome gedrückt und wählen Sie Cache leeren und hart neu laden aus, damit Ihr Service Worker aktualisiert wird.
- Stellen Sie in der Drop-down-Liste Throttling (Drosselung) wieder Offline ein.
- Geben Sie eine Suchanfrage ein und klicken Sie noch einmal auf die Schaltfläche Suchen.
- Klicke auf Benachrichtigungen abonnieren.
- Wenn Sie in Chrome gefragt werden, ob Sie der App die Berechtigung zum Senden von Benachrichtigungen erteilen möchten, klicken Sie auf Zulassen.
- Geben Sie eine weitere Suchanfrage ein und klicken Sie noch einmal auf die Schaltfläche Suchen.
- Stellen Sie in der Drop-down-Liste Throttling (Drosselung) wieder Online ein.
Sobald die Verbindung wiederhergestellt ist, wird eine Benachrichtigung angezeigt:
Fazit
Workbox bietet viele integrierte Funktionen, mit denen Sie Ihre PWAs robuster und ansprechender gestalten können. In diesem Codelab haben Sie gelernt, wie Sie die Background Sync API über die Workbox-Abstraktion implementieren, damit Offlineabfragen von Nutzern nicht verloren gehen und nach Wiederherstellung der Verbindung noch einmal versucht werden können. Die Demo ist eine einfache Such-App, aber Sie können eine ähnliche Implementierung auch für komplexere Szenarien und Anwendungsfälle verwenden, z. B. für Chat-Apps oder das Posten von Nachrichten in einem sozialen Netzwerk.