Obsługa żądań nawigacji

Reaguj na żądania nawigacji bez oczekiwania na połączenie z siecią, korzystając z skryptu service worker.

Żądania dotyczące nawigacji to żądania dotyczące 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 prowadzący do nowego adresu. W tym przypadku największy wpływ na wydajność mają mechanizmy Service Worker. Jeśli używasz ich do odpowiadania na żądania nawigacji bez oczekiwania na połączenie z siecią, możesz zadbać o niezawodną nawigację, a także odporność na niedostępność sieci. To największa pojedyncza wygrana dzięki skryptom service worker w porównaniu z buforowaniem pamięci podręcznej HTTP.

Zgodnie z opisem w przewodniku Identyfikowanie zasobów ładowanych z sieci żądanie nawigacji jest pierwszym z potencjalnie wielu żądań wysyłanych do „kaskady” ruchu sieciowego. Kod HTML, który wczytujesz za pomocą żądania nawigacji, uruchamia przepływ wszystkich innych żądań dotyczących zasobów podrzędnych, takich jak obrazy, skrypty i style.

W module obsługi zdarzeń fetch w skrypcie service worker możesz określić, czy żądanie jest nawigacją, sprawdzając właściwość request.mode w FetchEvent. Jeśli ustawiona jest wartość 'navigate', jest to żądanie nawigacyjne.

Generalnie nie używaj długotrwałego atrybutu Cache-Control headers do zapisywania odpowiedzi HTML w pamięci podręcznej na potrzeby żądania nawigacji. Zwykle powinny być przesyłane przez sieć z elementem Cache-Control: no-cache, by mieć pewność, że kod HTML oraz łańcuch kolejnych żądań sieciowych są (rozsądnie) aktualne. Nieuzasadnione przejście do sieci za każdym razem, gdy użytkownik otwiera nową stronę, powoduje niestety, że każda nawigacja może działać wolno. Przynajmniej oznacza to, że nie będzie on niezawodnie szybka.

Różne podejścia do architektur

Opracowanie sposobu odpowiadania na żądania nawigacji bez połączenia z siecią może być trudne. Odpowiednie podejście zależy w dużej mierze od architektury Twojej witryny i liczby unikalnych adresów URL, do których mogą przechodzić użytkownicy.

Nie ma jednego uniwersalnego rozwiązania, ale poniższe ogólne wytyczne pomogą Ci w wyborze najodpowiedniejszego podejścia.

Małe witryny statyczne

Jeśli Twoja aplikacja internetowa składa się ze stosunkowo małej liczby (np. kilkudziesiąt) unikalnych adresów URL, a każdy z nich odpowiada innemu statycznemu plikowi HTML, dobrym sposobem jest przechowywanie wszystkich tych plików HTML w pamięci podręcznej i reagowanie na żądania nawigacji z użyciem odpowiedniego kodu HTML przechowywanego w pamięci podręcznej.

Używając funkcji wstępnego buforowania, możesz z wyprzedzeniem zapisać kod HTML w pamięci podręcznej, gdy tylko skrypt service worker zostanie zainstalowany, oraz aktualizować kod HTML z pamięci podręcznej za każdym razem, gdy odbudowujesz witrynę i ponownie wdrażasz skrypt service worker.

Z drugiej strony – jeśli nie chcesz wstępnie zapisywać całego kodu HTML – na przykład dlatego, że użytkownicy zwykle otwierają tylko niektóre adresy URL w witrynie – możesz zastosować strategię buforowania w czasie działania nieużywaj w czasie, gdy ponownie weryfikujesz. Zachowaj jednak ostrożność, bo każdy dokument HTML jest zapisywany w pamięci podręcznej i aktualizowany oddzielnie. Korzystanie z buforowania w czasie działania 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 chcesz, aby były one ponownie weryfikowane niezależnie od siebie.

Aplikacje jednostronicowe

Nowoczesne aplikacje internetowe często wykorzystują architekturę jednostronicową. 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ą. Pozwala to stworzyć „symulowaną” nawigację. Kolejne sposoby nawigacji mogą być „fałszywe”, ale początkowa nawigacja jest prawdziwa i ważne jest, aby nie była blokowana w sieci.

Jeśli korzystasz z architektury jednostronicowej, możesz korzystać z prostego wzorca do obsługi początkowego nawigacji z pamięci podręcznej: powłoki aplikacji. W tym modelu mechanizm Service Worker odpowiada na żądania nawigacji, zwracając ten sam pojedynczy plik HTML, który został już zapisany w pamięci podręcznej – niezależnie od żądania adresu URL. Kod HTML powinien być pozbawiony elementów i zawierać np. ogólny wskaźnik wczytywania lub szkielet zawartości. Gdy przeglądarka załaduje ten kod HTML z pamięci podręcznej, istniejący kod JavaScript działający po stronie klienta przejmuje i renderuje prawidłową treść HTML dla tego adresu URL z pierwotnego żądania nawigacji.

Pole Workbox zawiera narzędzia potrzebne do stosowania tego podejścia. Pole navigateFallback option umożliwia określenie dokumentu HTML, którego chcesz użyć jako powłoki 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 witryny dynamicznie lub jeśli masz więcej niż kilkadziesiąt niepowtarzalnych stron, znacznie trudniej będzie unikać sieci podczas obsługi żądań nawigacyjnych. Wskazówki podane w sekcji Pozostałe prawdopodobnie pomogą Ci rozwiązać problem.

Jednak w przypadku niektórych aplikacji wielostronicowych możesz zaimplementować mechanizm Service Worker, który w pełni powiela mechanizmy logiczne używane na serwerze WWW do generowania kodu HTML. Jest to najlepsze rozwiązanie, jeśli możesz udostępniać informacje o routingu i szablonach między środowiskami serwera i skryptów service worker, a zwłaszcza wtedy, gdy Twój serwer WWW korzysta z JavaScriptu (bez korzystania z funkcji specyficznych dla Node.js, takich jak dostęp do systemu plików).

Jeśli Twój serwer WWW należy do tej kategorii i chcesz wypróbować jedną z metod przenoszenia generowania kodu HTML z sieci i do skryptu service worker, zacznij od zapoznania się ze wskazówkami z artykułu Poza SPA: alternatywne architektury dla aplikacji PWA.

Wszystkie pozostałe

Jeśli nie możesz odpowiadać na żądania nawigacyjne za pomocą kodu HTML przechowywanego w pamięci podręcznej, musisz zadbać o to, by dodanie do witryny skryptu service worker (do obsługi innych żądań w formacie innym niż HTML) nie spowalniało nawigacji. Uruchomienie skryptu service worker bez użycia go do reagowania na żądanie nawigacji spowoduje niewielkie opóźnienia (zgodnie z opisem w sekcji Szybsze tworzenie aplikacji za pomocą mechanizmu Service Worker). Aby zmniejszyć nakład pracy, włącz funkcję wstępne wczytywanie nawigacji, a potem użyj odpowiedzi sieci, która została wstępnie wczytana w module obsługi zdarzeń fetch.

Workbox udostępnia bibliotekę pomocniczą, która wykrywa, czy wstępne wczytywanie nawigacji jest obsługiwane. Jeśli tak, upraszcza proces instruowania skryptu service worker o używanie odpowiedzi sieciowej.

Fot. Aaron Burden, Unsplash