Obsługa żądań nawigacji

Odpowiadaj na żądania nawigacji bez oczekiwania na sieć, korzystając z skryptu service worker.

Żądania nawigacji to żądania dokumentów HTML wysyłane przez przeglądarkę za każdym razem, gdy wpiszesz nowy adres URL na pasku nawigacyjnym lub klikniesz link na stronie przekierowujący do nowego adresu URL. W tym przypadku mechanizmy Service Worker mają największy wpływ na wydajność. Jeśli korzystasz z skryptów usługi, które odpowiadają na żądania nawigacji bez oczekiwania na sieć, możesz zapewnić niezawodną nawigację i odporność w przypadku niedostępności sieci. Jest to pojedyncza największa korzyść w zakresie wydajności, jaką uzyskuje skrypt service worker w porównaniu z tym, co jest możliwe w przypadku buforowania HTTP.

Jak opisano w przewodniku Identyfikowanie zasobów wczytywanych z sieci, żądanie nawigacji to pierwsze z potencjalnie wielu żądań wysyłanych w kaskadzie ruchu w sieci. Kod HTML wczytywany w żądaniu nawigacji uruchamia przepływ wszystkich innych żądań zasobów podrzędnych, takich jak obrazy, skrypty i style.

W obrębie modułu obsługi zdarzeń fetch skryptu service worker możesz ustalić, czy żądanie jest nawigacji, sprawdzając w FetchEvent właściwość request.mode. Jeśli ma wartość 'navigate', jest to żądanie nawigacji.

Ogólnie rzecz biorąc, do zapisywania odpowiedzi HTML na żądanie nawigacji w pamięci podręcznej nie używaj długoterminowego parametru Cache-Control headers. Zazwyczaj żądania są realizowane przez sieć (Cache-Control: no-cache), dzięki czemu kod HTML i łańcuch kolejnych żądań sieciowych są (raczej) aktualne. Korzystanie z sieci przy każdym otwarciu nowej strony przez użytkownika oznacza niestety, że każda nawigacja może przebiegać wolno. Oznacza to przynajmniej, że nie będzie to niezawodnie szybkie.

Różne podejścia do architektur

Ustalenie, jak odpowiadać na żądania nawigacji przy jednoczesnym unikaniu połączenia z siecią, może być wyzwaniem. Właściwe podejście w dużej mierze zależy od architektury witryny i liczby niepowtarzalnych adresów URL, które mogą odwiedzać użytkownicy.

Chociaż nie ma jednego uniwersalnego rozwiązania, poniższe wskazówki powinny pomóc w podjęciu decyzji, które podejście jest najkorzystniejsze.

Małe witryny statyczne

Jeśli Twoja aplikacja internetowa składa się ze stosunkowo małej liczby (kilkunastu) unikalnych adresów URL, a każdy z nich odpowiada innemu statycznemu plikowi HTML, możesz zapisać wszystkie te pliki HTML w pamięci podręcznej i odpowiadać na żądania nawigacji odpowiednim kodem HTML z pamięci podręcznej.

Korzystając z wstępnego zapisywania w pamięci podręcznej, możesz z wyprzedzeniem zapisać kod HTML w pamięci podręcznej zaraz po zainstalowaniu skryptu service worker, a także aktualizować kod HTML z pamięci podręcznej za każdym razem, gdy odbudujesz witrynę i wdrożysz mechanizm Service Worker.

Z kolei, jeśli wolisz unikać wstępnego zapisywania kodu HTML w pamięci podręcznej – być może dlatego, że użytkownicy zwykle przechodzą do podzbioru adresów URL w Twojej witrynie, możesz zastosować strategię nieaktywnego podczas ponownego weryfikowania czasu działania. Zachowaj jednak ostrożność, ponieważ każdy dokument HTML jest przechowywany w pamięci podręcznej i aktualizowany oddzielnie. Używanie buforowania w czasie działania w przypadku kodu HTML jest najbardziej odpowiednie, jeśli masz niewielką liczbę adresów URL, które są często odwiedzane przez tę samą grupę użytkowników, i jeśli nie przeszkadza Ci, że te adresy są ponownie weryfikowane niezależnie od siebie.

Aplikacje jednostronicowe

Architektura jednostronicowa jest często stosowana przez nowoczesne aplikacje internetowe. Kod JavaScript po stronie klienta modyfikuje kod HTML w odpowiedzi na działania użytkownika. Ten model używa interfejsu History API, aby modyfikować bieżący adres URL w miarę interakcji użytkownika z aplikacją internetową, co jest tzw. „symulowaną” nawigacją. Kolejne opcje nawigacji mogą być „fałszywe”, jednak początkowa nawigacja jest prawidłowa i nadal ważne jest, aby nie blokować jej w sieci.

Na szczęście w przypadku architektury jednostronicowej obowiązuje prosty wzorzec wyświetlania początkowej nawigacji z pamięci podręcznej: powłoka aplikacji. W tym modelu mechanizm Service Worker odpowiada na żądania nawigacji, zwracając ten sam pojedynczy plik HTML, który został już umieszczony w pamięci podręcznej – niezależnie od żądanego adresu URL. Kod HTML powinien być krótki, na przykład zawierać ogólny wskaźnik wczytywania lub szkielet treści. Gdy przeglądarka załaduje ten kod HTML z pamięci podręcznej, istniejący kod JavaScript po stronie klienta przejmuje kontrolę i wyrenderuje właściwą treść HTML dla adresu URL z pierwotnego żądania nawigacji.

Workbox zawiera narzędzia potrzebne do wdrożenia tego podejścia. navigateFallback option umożliwia określenie dokumentu HTML, który ma być powłoką aplikacji, oraz opcjonalną listę dozwolonych i odrzuconych, która ogranicza to działanie do podzbioru adresów URL.

Aplikacje wielostronicowe

Jeśli Twój serwer WWW generuje kod HTML dynamicznie lub masz kilkadziesiąt niepowtarzalnych stron, znacznie trudniej jest uniknąć sieci podczas obsługi żądań nawigacji. Wskazówka w sekcji Wszystkie pozostałe prawdopodobnie będzie Cię dotyczyła.

W przypadku niektórych aplikacji wielostronicowych można jednak wdrożyć mechanizm Service Worker, który w pełni powiela logikę używaną na serwerze WWW do generowania kodu HTML. To najlepsze rozwiązanie, gdy możesz udostępniać informacje o routingu i szablonach między serwerem a środowiskami instancji roboczych usługi, a zwłaszcza wtedy, gdy Twój serwer WWW używa JavaScriptu (bez korzystania z funkcji typowych dla Node.js, takich jak dostęp do systemu plików).

Jeśli Twój serwer WWW należy do tej kategorii i chcesz poznać jedną metodę przenoszenia generowania kodu HTML z sieci do mechanizmu Service Worker, pomocne mogą być wskazówki w artykule Poza rozwiązaniami SPA: alternatywne architektury PWA.

Wszystkie pozostałe

Jeśli nie możesz odpowiadać na żądania nawigacji za pomocą kodu HTML z pamięci podręcznej, musisz zadbać o to, by dodanie do witryny skryptu service worker (do obsługi innych żądań niebędących żądaniami HTML) nie spowalniał nawigacji. Uruchomienie skryptu service worker bez użycia go do reagowania na żądanie nawigacji spowoduje niewielkie opóźnienie (jak wyjaśniono w artykule Szybsze tworzenie aplikacji z większą odpornością). Aby zmniejszyć te narzuty, włącz funkcję o nazwie wstępne wczytywanie nawigacji, a następnie użyj odpowiedzi sieciowej, która została wstępnie wczytana w module obsługi zdarzeń fetch.

Workbox zapewnia bibliotekę pomocniczą, która wykrywa, czy wstępne wczytywanie nawigacji jest obsługiwane, a jeśli tak, upraszcza proces nakazania skryptowi usługi usługi użycia odpowiedzi sieci.

Zdjęcie: Aaron Burden na kanale Unsplash