Pamięć podręczna to potężne narzędzie. Dzięki temu aplikacje są mniej zależne od warunków sieci. Odpowiednio wykorzystujesz pamięć podręczną, by udostępnić swoją aplikację internetową w trybie offline i jak najszybciej wyświetlać zasoby w każdej sieci. Jak wspomnieliśmy w sekcji Komponenty i dane, możesz wybrać najlepszą strategię dotyczącą buforowania niezbędnych komponentów. Aby zarządzać pamięcią podręczną, usługa robocza wchodzi w interakcję z interfejsem Cache Storage API.
Interfejs Cache Storage API jest dostępny w różnych kontekstach:
- kontekst okna (główny wątek aplikacji PWA);
- Skrypt service worker.
- Inne używane przez Ciebie instancje robocze.
Jedną z zalet zarządzania pamięcią podręczną za pomocą mechanizmów Service Worker jest to, że ich cykl życia nie jest powiązany z oknem, co oznacza, że nie blokujesz wątku głównego. Pamiętaj, że aby korzystać z interfejsu Cache Storage API, większość tych kontekstów musi być chroniona przez połączenie TLS.
Co zapisać w pamięci podręcznej
Pierwsze pytanie dotyczące buforowania dotyczy tego, co należy przechowywać w pamięci podręcznej. Nie ma jednej odpowiedzi na to pytanie, ale możesz zacząć od wszystkich minimalnych zasobów potrzebnych do renderowania interfejsu użytkownika.
Zasoby te powinny obejmować:
- Kod HTML strony głównej (start_url aplikacji).
- Pliki czcionek CSS potrzebne do głównego interfejsu użytkownika.
- Obrazy używane w interfejsie.
- pliki JavaScript wymagane do renderowania interfejsu użytkownika;
- Dane, takie jak plik JSON, są wymagane do renderowania podstawowego.
- czcionki internetowe.
- W przypadku aplikacji wielostronicowej inne dokumenty HTML, które mają być szybko wyświetlane lub dostępne w trybie offline.
Tryb offline
Chociaż obsługa trybu offline jest jednym z wymagań dotyczących progresywnych aplikacji internetowych, należy pamiętać, że nie każda PWA wymaga pełnej obsługi trybu offline, np. rozwiązania do gier w chmurze czy aplikacje do zarządzania kryptowalutami. Warto więc udostępnić podstawowy interfejs, który będzie pomocny w takich sytuacjach.
PWA nie powinna wyświetlać komunikatu o błędzie przeglądarki informującego, że mechanizm renderowania stron internetowych nie mógł wczytać strony. Zamiast tego użyj workera usługi, aby wyświetlać własne komunikaty, unikając ogólnego i niejasnego błędu w przeglądarce.
W zależności od potrzeb aplikacji internetowej możesz stosować różne strategie dotyczące pamięci podręcznej. Dlatego ważne jest, aby zaprojektować wykorzystanie pamięci podręcznej w sposób zapewniający szybkie i niezawodne działanie. Jeśli na przykład wszystkie zasoby aplikacji będą pobierane szybko, nie będą zajmować dużo miejsca i nie będą wymagać aktualizacji w przypadku każdej prośby, odpowiednią strategią będzie zainstalowanie wszystkich zasobów w pamięci podręcznej. Jeśli jednak masz zasoby, które muszą być w najnowszej wersji, możesz rozważyć całkowite wyłączenie ich buforowania.
Korzystanie z interfejsu API
Użyj interfejsu Cache Storage API, aby zdefiniować zestaw pamięci podręcznej w pochodzeniu, z których każdy jest identyfikowany za pomocą nazwy ciągu znaków, którą możesz zdefiniować. Uzyskaj dostęp do interfejsu API za pomocą obiektu caches
, a metoda open
umożliwia utworzenie lub otwarcie już utworzonej pamięci podręcznej. Metoda open zwraca obietnicę dla obiektu pamięci podręcznej.
caches.open("pwa-assets")
.then(cache => {
// you can download and store, delete or update resources with cache arguments
});
Pobieranie i przechowywanie zasobów
Aby poprosić przeglądarkę o pobieranie i przechowywanie zasobów, użyj metod add
lub addAll
. Metoda add
wysyła żądanie i zapisuje 1 odpowiedź HTTP, a addAll
– grupę odpowiedzi HTTP jako transakcję opartą na tablicy żądań lub adresów URL.
caches.open("pwa-assets")
.then(cache => {
cache.add("styles.css"); // it stores only one resource
cache.addAll(["styles.css", "app.js"]); // it stores two resources
});
Interfejs pamięci podręcznej przechowuje całą odpowiedź, w tym wszystkie nagłówki i treść. Dzięki temu możesz go później pobrać, używając żądania HTTP lub adresu URL jako klucza. Więcej informacji znajdziesz w rozdziale dotyczącym wyświetlania.
Kiedy stosować pamięć podręczną
W przypadku aplikacji PWA to Ty decydujesz, kiedy pliki mają być buforowane. Jednym z podejść jest przechowywanie jak największej liczby zasobów po zainstalowaniu pracownika usługi, ale zwykle nie jest to najlepszy pomysł. Buforowanie niepotrzebnych zasobów marnuje przepustowość i miejsce na dane oraz może spowodować, że aplikacja będzie wyświetlać niechciane nieaktualne zasoby.
Nie musisz zapisywać w pamięci podręcznej wszystkich zasobów jednocześnie. Zasoby możesz zapisywać w pamięci podręcznej wiele razy w trakcie cyklu życia aplikacji PWA, na przykład:
- Po zainstalowaniu skryptu service worker.
- Po pierwszym wczytaniu strony.
- Gdy użytkownik przechodzi do danego odcinka lub trasy.
- Gdy sieć jest nieaktywna.
Możesz poprosić o zapisanie nowych plików w głównym wątku lub w kontekście usługi workera.
Buforowanie zasobów w usługach worker
Jednym z najczęstszych scenariuszy jest buforowanie minimalnego zestawu zasobów po zainstalowaniu pracownika usługi. W tym celu możesz użyć interfejsu pamięci podręcznej w ramach zdarzenia install
w usługach działających w tle.
Wątek usługi może zostać zatrzymany w dowolnym momencie, dlatego możesz poprosić przeglądarkę, aby zaczekała na zakończenie addAll
obietnicy, co zwiększy szansę na przechowywanie wszystkich zasobów i utrzymanie spójności aplikacji. Przykład poniżej pokazuje, jak to zrobić, używając metody waitUntil
argumentu zdarzenia otrzymanego w odbiorniku zdarzeń dla usługi workera.
const urlsToCache = ["/", "app.js", "styles.css", "logo.svg"];
self.addEventListener("install", event => {
event.waitUntil(
caches.open("pwa-assets")
.then(cache => {
return cache.addAll(urlsToCache);
});
);
});
Metoda waitUntil()
otrzymuje obietnicę i prosi przeglądarkę o poczekanie, aż zadanie w obietnicy zostanie zakończone (z wynikiem powodzenia lub niepowodzenia), zanim proces workera usługi zostanie zakończony. Może być konieczne złączenie obietnic i zwrócenie wywołań add()
lub addAll()
, aby metoda waitUntil()
otrzymała pojedynczy wynik.
Obietki obietnicy możesz też obsługiwać za pomocą składni async/await. W takim przypadku musisz utworzyć funkcję asynchroniczną, która może wywołać funkcję await
i zwracać obietnicę dla funkcji waitUntil()
po jej wywołaniu, jak w tym przykładzie:
const urlsToCache = ["/", "app.js", "styles.css", "logo.svg"];
self.addEventListener("install", (event) => {
let cacheUrls = async () => {
const cache = await caches.open("pwa-assets");
return cache.addAll(urlsToCache);
};
event.waitUntil(cacheUrls());
});
Żądania między domenami i nieprzezroczyste odpowiedzi
PWA może pobierać zasoby z źródła i z domeny krzyżowej oraz przechowywać je w pamięci podręcznej, np. treści z zewnętrznych sieci CDN. W przypadku aplikacji między domenami interakcja z pamięcią podręczną jest bardzo podobna do żądań z tego samego pochodzenia. Żądanie jest wykonywane, a kopia odpowiedzi jest przechowywana w pamięci podręcznej. Tak jak w przypadku innych zasobów zapisanych w pamięci podręcznej, można go używać tylko w pierwotnej wersji aplikacji.
Zasób zostanie zapisany jako nieprzezroczysta odpowiedź, co oznacza, że Twój kod nie będzie mógł zobaczyć ani zmodyfikować zawartości ani nagłówków tej odpowiedzi. Poza tym nieprzezroczyste odpowiedzi nie ujawniają swojego rzeczywistego rozmiaru w interfejsie Storage API, co ma wpływ na limity. Niektóre przeglądarki wyświetlają duże rozmiary, np. 7 MB, niezależnie od tego, czy plik ma tylko 1 KB.
Aktualizowanie i usuwanie zasobów
Zasoby możesz aktualizować za pomocą cache.put(request, response)
, a usuwać za pomocą delete(request)
.
Aby dowiedzieć się więcej, zapoznaj się z dokumentacją obiektu pamięci podręcznej.
Debugowanie pamięci podręcznej
Wiele przeglądarek umożliwia debugowanie zawartości pamięci podręcznej na karcie Aplikacja w Narzędziach deweloperskich. Możesz tam zobaczyć zawartość każdej pamięci podręcznej w ramach bieżącego źródła. Więcej informacji o tych narzędziach znajdziesz w rozdziale poświęconym narzędziom i debugowaniu.