Zastąpienie tradycyjnych technik pobierania z wyprzedzeniem mechanizmami service worker.
Wykonanie zadania w witrynie zwykle wymaga wykonania kilku czynności. Przykład: zakup produktu w witrynie e-commerce może obejmować wyszukanie produktu, wybranie go z listy wyników, dodanie go do koszyka i wykonanie operacji przez płacenie.
Z technicznego punktu widzenia poruszanie się po różnych stronach oznacza wysłanie żądania nawigacji. Zazwyczaj nie chcesz używać długotrwałych nagłówków Cache-Control
do buforowania odpowiedzi HTML na potrzeby żądania nawigacji. Zwykle przesyła się je przez sieć z elementem Cache-Control: no-cache
, by mieć pewność, że kod HTML oraz łańcuch kolejnych żądań sieciowych są (rozsądnie) aktualne.
Jeśli użytkownik musi wejść na nową stronę, musi on z łatwością połączyć się z siecią przy każdym otwarciu nowej strony, co oznacza, że niestety każda nawigacja może działać wolno, a przynajmniej oznacza, że nie będzie działać niezawodnie.
Aby przyspieszyć przetwarzanie tych żądań, jeśli możesz przewidzieć działanie użytkownika, możesz wcześniej poprosić o dostęp do tych stron i zasobów i zachować je w pamięci podręcznej przez krótki czas, dopóki użytkownik nie kliknie tych linków. Ta technika nosi nazwę pobierania z wyprzedzeniem i jest powszechnie stosowana przez dodanie do stron tagów <link rel="prefetch">
, które wskazują zasób do pobrania z wyprzedzeniem.
W tym przewodniku omówimy różne sposoby stosowania skryptów service worker jako uzupełnienie tradycyjnych technik pobierania z wyprzedzeniem.
Przypadki produkcyjne
MercadoLibre to największa witryna e-commerce w Ameryce Łacińskiej. Aby przyspieszyć nawigację, w niektórych częściach procesu wstawiane są dynamicznie tagi <link rel="prefetch">
. Na przykład w przypadku stron z listą wyników pobierają następną stronę wyników, gdy tylko użytkownik przewinie stronę na sam dół:
Wczytywane z wyprzedzeniem pliki są żądane z „najniższym” priorytetem i przechowywane w pamięci podręcznej HTTP lub w pamięci podręcznej stanu strony internetowej (w zależności od tego, czy zasób jest buforowany) przez czas, który różni się w zależności od przeglądarki. Na przykład w Chrome 85 ta wartość wynosi 5 minut. Zasoby są przechowywane przez 5 minut. Po tym czasie obowiązują normalne reguły Cache-Control
dotyczące tego zasobu.
Użycie pamięci podręcznej skryptu service worker może wydłużyć czas życia zasobów pobierania z wyprzedzeniem poza 5-minutowy okres.
Na przykład włoski portal sportowy Virgilio Sport używa pracowników usług do pobierania z wyprzedzeniem najpopularniejszych postów ze strony głównej. Korzystają też z interfejsu Network Information API, aby zapobiegać pobieraniu z wyprzedzeniem w przypadku użytkowników korzystających z połączenia 2G.
W rezultacie w ciągu 3 tygodni obserwacji firma Virgilio Sport odnotowała czas wczytywania artykułów poprawiony o 78%, a liczba wyświetleń artykułów wzrosła o 45%.
Wdrażanie wstępnego buforowania za pomocą Workbox
W kolejnej sekcji wykorzystamy Workbox, aby pokazać, jak wdrożyć w mechanizmie Service Worker różne techniki buforowania, które można wykorzystać jako uzupełnienie <link rel="prefetch">
lub nawet zastępujące, całkowicie przekazując to zadanie skryptowi service worker.
1. Wstępnie buforuj strony statyczne i podrzędne strony
Dopuszczanie w pamięci podręcznej to możliwość zapisywania plików w pamięci podręcznej przez skrypt service worker podczas instalacji.
W tych przypadkach wstępne wczytywanie służy do osiągnięcia celu podobnego do wczytywania z wyprzedzeniem, czyli przyspieszenia nawigacji.
Blokowanie stron statycznych w pamięci podręcznej
W przypadku stron generowanych podczas kompilacji (np.about.html
, contact.html
) lub w całkowicie statycznych witrynach można po prostu dodać dokumenty witryny do listy z pamięci podręcznej. Dzięki temu będą one już dostępne w pamięci podręcznej za każdym razem, gdy użytkownik uzyska do nich dostęp:
workbox.precaching.precacheAndRoute([
{url: '/about.html', revision: 'abcd1234'},
// ... other entries ...
]);
Zasoby podrzędne strony wstępnego buforowania
Stosowanie w pamięci podręcznej zasobów statycznych, z których mogą korzystać różne sekcje witryny (np. JavaScript, CSS itp.), to ogólna sprawdzona metoda, która może dodatkowo zwiększyć skuteczność w przypadku scenariuszy pobierania z wyprzedzeniem.
Aby przyspieszyć nawigację w witrynie e-commerce, możesz użyć tagów <link rel="prefetch">
na stronach z informacjami o produktach, aby z wyprzedzeniem pobierać strony ze szczegółami produktów w przypadku kilku pierwszych produktów na stronie z informacjami. Jeśli masz już w pamięci podręcznej strony produktów, nawigacja może być jeszcze szybsza.
Aby to zrobić:
- Dodaj do strony tag
<link rel="prefetch">
:
<link rel="prefetch" href="/phones/smartphone-5x.html" as="document">
- Dodaj zasoby podrzędne stron do listy pamięci podręcznej w skrypcie service worker:
workbox.precaching.precacheAndRoute([
'/styles/product-page.ac29.css',
// ... other entries ...
]);
2. Wydłuż okres ważności zasobów pobierania z wyprzedzeniem
Jak już wspomnieliśmy, <link rel="prefetch">
pobiera zasoby i przechowuje je w pamięci podręcznej HTTP przez ograniczony czas. Po tym czasie obowiązują reguły Cache-Control
dotyczące zasobu. Od wersji Chrome 85 ta wartość wynosi 5 minut.
Skrypty service worker pozwalają wydłużyć czas trwania stron pobierania z wyprzedzeniem, jednocześnie zapewniając dodatkowe korzyści w postaci udostępnienia tych zasobów do użytku w trybie offline.
W poprzednim przykładzie można uzupełnić atrybut <link rel="prefetch">
używany do wstępnego pobierania strony produktu za pomocą strategii buforowania środowiska wykonawczego w Workbox.
Aby to zrobić:
- Dodaj do strony tag
<link rel="prefetch">
:
<link rel="prefetch" href="/phones/smartphone-5x.html" as="document">
- W przypadku tych typów żądań zaimplementuj w skrypcie service worker strategię buforowania w czasie działania:
new workbox.strategies.StaleWhileRevalidate({
cacheName: 'document-cache',
plugins: [
new workbox.expiration.Plugin({
maxAgeSeconds: 30 * 24 * 60 * 60, // 30 Days
}),
],
});
W tym przypadku zdecydowaliśmy się użyć strategii „nieaktualny w trakcie ponownej weryfikacji”. W tej strategii żądania stron można wysyłać równolegle z pamięci podręcznej i z sieci. Odpowiedź pochodzi z pamięci podręcznej (jeśli jest dostępna) lub z sieci. Pamięć podręczna jest zawsze aktualizowana odpowiedzią sieciową po każdym pomyślnym żądaniu.
3. Przekazywanie wstępnego pobierania do skryptu service worker
W większości przypadków najlepszym rozwiązaniem jest użycie interfejsu <link rel="prefetch">
. Tag jest wskazówką dotyczącą zasobów, która ma na celu jak najwydajniejsze pobieranie z wyprzedzeniem.
Jednak w niektórych przypadkach lepiej jest przekazać to zadanie w całości skryptowi service worker.
Przykład: aby pobrać z wyprzedzeniem kilka pierwszych produktów ze strony z informacjami wyrenderowaną po stronie klienta, konieczne może być dynamiczne wstrzyknięcie na stronie kilku tagów <link rel="prefetch">
w zależności od odpowiedzi interfejsu API. Może to zużywać więcej czasu w głównym wątku strony i utrudniać implementację.
W takich przypadkach użyj „strategii komunikacji między skryptami stron a platformy Service Worker”, aby przekazać zadanie wczytywania z wyprzedzeniem do skryptu service worker. Komunikację tego typu można uzyskać za pomocą funkcji worker.postMessage():
Pakiet okna okna roboczego upraszcza ten typ komunikacji, pochłaniając wiele szczegółów dotyczących wykonywanego wywołania.
Pobieranie z wyprzedzeniem w oknie skrzynki roboczej można zaimplementować w taki sposób:
- Na stronie: wywołaj skrypt service worker, przekazując do niego typ komunikatu i listę adresów URL do pobrania z wyprzedzeniem:
const wb = new Workbox('/sw.js');
wb.register();
const prefetchResponse = await wb.messageSW({type: 'PREFETCH_URLS', urls: […]});
- W skrypcie service worker: zaimplementuj moduł obsługi wiadomości, by wysyłać żądanie
fetch()
dla każdego adresu URL z wyprzedzeniem:
addEventListener('message', (event) => {
if (event.data.type === 'PREFETCH_URLS') {
// Fetch URLs and store them in the cache
}
});