Z tego modułu dowiesz się, jak wdrożyć odporne wyszukiwanie za pomocą Workbox. Aplikacja demonstracyjna, której używa, zawiera pole wyszukiwania, które wywołuje punkt końcowy serwera i przekierowuje użytkownika na podstawową stronę HTML.
Pomiary
Zanim zaczniesz wprowadzać optymalizacje, warto najpierw przeanalizować obecny stan aplikacji.
- Kliknij Remiksuj, aby edytować, aby umożliwić edycję projektu.
- Aby wyświetlić podgląd strony, kliknij Wyświetl aplikację, a następnie Pełny ekran
.
Na nowo otwartej karcie sprawdź, jak witryna zachowuje się po przejściu w tryb offline:
- Aby otworzyć Narzędzia dla programistów, naciśnij Ctrl+Shift+J (lub Command+Option+J na Macu).
- Kliknij kartę Sieć.
- Otwórz Narzędzia deweloperskie w Chrome i wybierz panel Sieć.
- Z listy ograniczania wybierz Offline.
- W aplikacji demonstracyjnej wpisz zapytanie, a potem kliknij przycisk Szukaj.
Wyświetli się standardowa strona błędu przeglądarki:
Podaj odpowiedź zastępczą
Service worker zawiera kod, który dodaje stronę offline do listy wstępnego buforowania, dzięki czemu zawsze może być buforowana podczas zdarzenia install
service worker.
Zwykle musisz poinstruować Workbox, aby dodał ten plik do listy wstępnego buforowania w czasie kompilacji, integrując bibliotekę z wybranym narzędziem do kompilacji (np. webpack lub gulp).
Aby uprościć ten proces, zrobiliśmy to za Ciebie. Ten kod w pliku public/sw.js
wykonuje takie operacje:
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 rezerwowej:
- Aby wyświetlić źródło, naciśnij Wyświetl źródło.
- Dodaj ten kod na końcu pliku
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 działania:
- Określa 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()
, aby zarządzać nieudanymi żądaniami. W przypadku żądań dotyczących dokumentów zwracana jest zastępcza strona HTML offline.
Aby przetestować tę funkcję:
- Wróć na drugą kartę, na której działa aplikacja.
- Zmień ustawienie na liście Ograniczanie z powrotem na Online.
- Naciśnij przycisk Wstecz w Chrome, aby wrócić na stronę wyszukiwania.
- Upewnij się, że pole wyboru Disable cache (Wyłącz pamięć podręczną) w Narzędziach deweloperskich jest odznaczone.
- Naciśnij i przytrzymaj przycisk Odśwież w Chrome i wybierz Wyczyść pamięć podręczną i odśwież stronę, aby mieć pewność, że Twój service worker został zaktualizowany.
- Z listy Ograniczanie ponownie wybierz Offline.
- Wpisz zapytanie i ponownie kliknij przycisk Szukaj.
Wyświetli się zastępcza strona HTML:
Prośba o zgodę na wyświetlanie powiadomień
Dla uproszczenia strona offline pod adresem views/index_offline.html
zawiera już kod do wysyłania prośby o uprawnienia do powiadomień w bloku skryptu u dołu:
function requestNotificationPermission(event) {
event.preventDefault();
Notification.requestPermission().then(function (result) {
showOfflineText(result);
});
}
Kod wykonuje te działania:
- Gdy użytkownik kliknie subskrybuj powiadomienia, wywoływana jest funkcja
requestNotificationPermission()
, która wywołuje funkcjęNotification.requestPermission()
, aby wyświetlić domyślny monit przeglądarki o uprawnienia. Obietnica jest spełniana z uprawnieniami wybranymi przez użytkownika, które mogą mieć wartośćgranted
,denied
lubdefault
. - Przekazuje rozwiązane uprawnienia do funkcji
showOfflineText()
, aby wyświetlić użytkownikowi odpowiedni tekst.
Utrzymywanie zapytań offline i ponawianie ich, gdy urządzenie znów będzie online
Następnie wdróż synchronizację w tle Workbox, aby utrwalać zapytania offline i ponawiać je, gdy przeglądarka wykryje przywrócenie łączności.
- Otwórz plik
public/sw.js
do edycji. - Na końcu pliku dodaj ten kod:
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 działania:
workbox.backgroundSync.Plugin
zawiera logikę dodawania nieudanych żądań do kolejki, aby można było ponowić ich wysyłanie w późniejszym czasie. Te żądania będą przechowywane w IndexedDB.maxRetentionTime
– wskazuje, ile razy można ponowić żądanie. W tym przypadku wybraliśmy 60 minut (po tym czasie zostanie odrzucony).onSync
to najważniejsza część tego kodu. To wywołanie zwrotne zostanie wywołane po przywróceniu połączenia, aby pobrać żądania w kolejce, a następnie pobrać je z sieci.- Odpowiedź sieci jest dodawana do pamięci podręcznej
offline-search-responses
z dołączonym parametrem zapytania¬ification=true
, dzięki czemu ten wpis w pamięci podręcznej może zostać pobrany, gdy użytkownik kliknie powiadomienie.
Aby zintegrować synchronizację w tle z usługą, zdefiniuj strategię NetworkOnly dla żądań wysyłanych na adres URL wyszukiwania (/search_action
) i przekaż wcześniej zdefiniowaną wartość bgSyncPlugin
. Dodaj ten kod na końcu pliku 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],
}),
);
Informuje to Workbox, że zawsze ma się łączyć z siecią, a gdy żądania się nie powiodą, ma używać logiki synchronizacji w tle.
Następnie dodaj ten kod na dole pliku public/sw.js
, aby zdefiniować strategię buforowania żądań pochodzących z powiadomień. Użyj strategii CacheFirst, aby można było je wyświetlać 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 wyświetlający 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 drugą kartę, na której działa aplikacja.
- Zmień ustawienie na liście Ograniczanie z powrotem na Online.
- Naciśnij przycisk Wstecz w Chrome, aby wrócić na stronę wyszukiwania.
- Naciśnij i przytrzymaj przycisk Odśwież w Chrome i wybierz Wyczyść pamięć podręczną i odśwież stronę, aby mieć pewność, że Twój service worker został zaktualizowany.
- Z listy Ograniczanie ponownie wybierz Offline.
- Wpisz zapytanie i ponownie kliknij przycisk Szukaj.
- Kliknij subskrybuj powiadomienia.
- Gdy Chrome zapyta, czy chcesz zezwolić aplikacji na wysyłanie powiadomień, kliknij Zezwól.
- Wpisz kolejne zapytanie i ponownie kliknij przycisk Szukaj.
- Z listy Ograniczanie ponownie wybierz Online.
Gdy połączenie zostanie przywrócone, pojawi się powiadomienie:
Podsumowanie
Workbox udostępnia wiele wbudowanych funkcji, które zwiększają odporność i zaangażowanie w przypadku PWA. W tym module praktycznym dowiedzieliśmy się, jak zaimplementować interfejs Background Sync API za pomocą abstrakcji Workbox, aby mieć pewność, że zapytania użytkowników offline nie zostaną utracone i będzie można je ponowić po przywróceniu połączenia. Wersja demonstracyjna to prosta aplikacja do wyszukiwania, ale podobne wdrożenie możesz wykorzystać w bardziej złożonych scenariuszach i przypadkach użycia, np. w aplikacjach do czatowania czy do publikowania wiadomości w sieci społecznościowej.