Z tego ćwiczenia w Codelabs dowiesz się, jak wdrożyć odporne środowisko wyszukiwania za pomocą aplikacji Workbox. Używana przez nią aplikacja w wersji demonstracyjnej zawiera pole wyszukiwania, które wywołuje punkt końcowy serwera i przekierowuje użytkownika na podstawową stronę HTML.
Zmierz odległość
Przed dodaniem optymalizacji zawsze warto najpierw przeanalizować bieżący stan aplikacji.
- Aby udostępnić projekt do edycji, kliknij Remiksuj, aby edytować.
- Aby wyświetlić podgląd strony, kliknij Wyświetl aplikację. Następnie naciśnij Pełny ekran
Na nowej karcie, która została właśnie otwarta, sprawdź, jak strona zachowuje się po przejściu do trybu offline:
- Naciśnij „Control + Shift + J” (lub „Command + Option + J” na Macu), aby otworzyć Narzędzia deweloperskie.
- Kliknij kartę Sieć.
- Otwórz Narzędzia deweloperskie w Chrome i kliknij panel Sieć.
- Z listy Ograniczanie wybierz Offline.
- W aplikacji w wersji demonstracyjnej wpisz zapytanie, a następnie kliknij przycisk Szukaj.
Wyświetlana jest standardowa strona błędu przeglądarki:
Podaj odpowiedź zastępczą
Skrypt service worker zawiera kod dodający stronę offline do listy precache, więc zawsze może być ona buforowana w zdarzeniu install
skryptu service worker.
Zwykle konieczne jest poinstruowanie Workbox, aby podczas kompilacji dodał ten plik do listy wstępnego bufora, integrując bibliotekę z wybranym narzędziem do kompilacji (np. webpack lub gulp).
Dla uproszczenia zrobiliśmy to już za Ciebie. Robi to następujący kod na stronie public/sw.js
:
const FALLBACK_HTML_URL = '/index_offline.html';
…
workbox.precaching.precacheAndRoute([FALLBACK_HTML_URL]);
Następnie dodaj kod, który będzie używać strony offline jako odpowiedzi zastępczej:
- Aby wyświetlić źródło, kliknij Wyświetl źródło.
- Dodaj ten kod na końcu
public/sw.js
:
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();
}
});
Kod wykonuje te czynności:
- Definiuje domyślną strategię Tylko sieć, która będzie stosowana do wszystkich żądań.
- Deklaruje globalny moduł obsługi błędów, wywołując funkcję
workbox.routing.setCatchHandler()
w celu zarządzania nieudanymi żądaniami. Gdy żądania dotyczą dokumentów, zwracana jest zastępcza strona HTML offline.
Aby przetestować tę funkcję:
- Wróć na inną kartę, na której działa Twoja aplikacja.
- Na liście Throttling ustaw ponownie opcję Online.
- Aby wrócić na stronę wyszukiwania, naciśnij przycisk Wstecz w Chrome.
- Upewnij się, że pole wyboru Wyłącz pamięć podręczną w Narzędziach deweloperskich jest wyłączone.
- Przytrzymaj przycisk Załaduj ponownie w Chrome i wybierz Opróżnij pamięć podręczną i ponownie załaduj ponownie , aby upewnić się, że skrypt service worker został zaktualizowany.
- Ponownie wybierz na liście Ograniczanie opcję Offline.
- Wpisz zapytanie i ponownie kliknij przycisk Szukaj.
Zobaczysz zastępczą stronę HTML:
Poproś o zgodę na wyświetlanie powiadomień
Dla uproszczenia strona offline pod adresem views/index_offline.html
zawiera już w bloku skryptu u dołu kod umożliwiający wysyłanie próśb o zgodę na wyświetlanie powiadomień:
function requestNotificationPermission(event) {
event.preventDefault();
Notification.requestPermission().then(function (result) {
showOfflineText(result);
});
}
Kod wykonuje te czynności:
- Gdy użytkownik kliknie Subskrybuj powiadomienia, wywoływana jest funkcja
requestNotificationPermission()
, która wywołuje funkcjęNotification.requestPermission()
, aby wyświetlić domyślną prośbę o przyznanie uprawnień przeglądarki. Obietnica rozwiązuje się, gdy użytkownik udzieli uprawnieńgranted
,denied
lubdefault
. - Przekazuje rozstrzygnięte uprawnienie usłudze
showOfflineText()
, aby użytkownik mógł wyświetlać odpowiedni tekst.
Zachowuj zapytania offline i ponów próbę, gdy odzyskasz połączenie z internetem
Następnie zaimplementuj synchronizację w tle z Workspace, aby zachować zapytania offline i móc je ponowić, gdy przeglądarka wykryje, że połączenie zostało przywrócone.
- Otwórz plik
public/sw.js
do edycji. - Dodaj ten kod na końcu pliku:
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;
}
}
},
});
Kod wykonuje te czynności:
workbox.backgroundSync.Plugin
zawiera logikę dodawania nieudanych żądań do kolejki, aby można było spróbować je później. Te żądania zostaną zachowane w IndexedDB.maxRetentionTime
wskazuje czas, przez jaki żądanie może być ponawiane. W tym przypadku wybieramy 60 minut (po tym czasie jest usuwany).- Najważniejszą częścią tego kodu jest
onSync
. To wywołanie zwrotne będzie wywoływane po przywróceniu połączenia, tak aby żądania w kolejce były pobierane z sieci. - Odpowiedź sieciowa jest dodawana do pamięci podręcznej
offline-search-responses
z dołączonym parametrem zapytania¬ification=true
, dzięki czemu ten wpis pamięci podręcznej może zostać przechwycony, gdy użytkownik kliknie powiadomienie.
Aby zintegrować synchronizację w tle ze swoją usługą, zdefiniuj strategię NetworkOnly dla żądań wysyłanych do adresu URL wyszukiwania (/search_action
) i przekaż wcześniej zdefiniowaną wartość bgSyncPlugin
. Dodaj ten kod na końcu public/sw.js
:
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],
}),
);
Dzięki temu aplikacja Workbox zawsze korzysta z sieci, a w przypadku niepowodzenia żądań używa logiki synchronizacji w tle.
Następnie dodaj poniższy kod na dole strony public/sw.js
, aby zdefiniować strategię buforowania dla żądań pochodzących z powiadomień. Użyj strategii CacheFirst, aby mogły być wyświetlane z pamięci podręcznej.
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',
})
);
Na koniec dodaj kod pozwalający wyświetlać powiadomienia:
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)
);
});
Testowanie funkcji
- Wróć na inną kartę, na której działa Twoja aplikacja.
- Na liście Throttling ustaw ponownie opcję Online.
- Aby wrócić na stronę wyszukiwania, naciśnij przycisk Wstecz w Chrome.
- Przytrzymaj przycisk Załaduj ponownie w Chrome i wybierz Opróżnij pamięć podręczną i ponownie załaduj ponownie , aby upewnić się, że skrypt service worker został zaktualizowany.
- Ponownie wybierz na liście Ograniczanie opcję Offline.
- Wpisz zapytanie i ponownie kliknij przycisk Szukaj.
- Kliknij Subskrybuj powiadomienia.
- Gdy Chrome zapyta, czy chcesz przyznać aplikacji uprawnienia do wysyłania powiadomień, kliknij Zezwól.
- Wpisz inne zapytanie i ponownie kliknij przycisk Szukaj.
- Ponownie ustaw na liście Ograniczanie opcję Online.
Po przywróceniu połączenia pojawi się powiadomienie:
Podsumowanie
Workbox ma wiele wbudowanych funkcji, dzięki którym Twoje aplikacje PWA są bardziej odporne i angażujące. W ramach tego ćwiczenia w Codelabs omówiliśmy, jak wdrożyć interfejs Background Sync API przy użyciu abstrakcji Workbox, aby mieć pewność, że zapytania offline nie zostaną utracone i można je powtarzać po przywróceniu połączenia. Wersja demonstracyjna to prosta aplikacja do wyszukiwania, ale w bardziej złożonych scenariuszach i przypadkach użycia możesz zastosować podobną implementację, np. komunikator internetowy czy publikowanie wiadomości w sieciach społecznościowych.