Pamięć podręczna to potężne narzędzie. Dzięki temu aplikacje są mniej zależne od warunków sieci. Dzięki odpowiedniemu wykorzystaniu pamięci podręcznej możesz udostępnić swoją aplikację internetową w trybie offline i wyświetlać komponenty tak szybko, jak to możliwe, w dowolnych warunkach sieciowych. 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.
- innych pracowników, których używasz;
Jedną z zalet zarządzania pamięcią podręczną za pomocą usług działających w tle jest to, że jej 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, które może Ci się nasunąć w związku z pamięcią podręczną, to co do niej zapisać. Nie ma jednej odpowiedzi na to pytanie, ale możesz zacząć od wszystkich minimalnych zasobów potrzebnych do renderowania interfejsu użytkownika.
Te zasoby powinny zawierać:
- Kod HTML strony głównej (start_url aplikacji).
- Plik czs.css jest potrzebny do głównego interfejsu użytkownika.
- Obrazy używane w interfejsie.
- pliki JavaScript wymagane do renderowania interfejsu użytkownika;
- Dane, np. plik JSON, wymagane do wyświetlenia podstawowej wersji.
- czcionki internetowe.
- W przypadku aplikacji wielostronicowej inne dokumenty HTML, które mają być wyświetlane szybko lub 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. Dlatego w takich sytuacjach można zaoferować użytkownikom podstawowy interfejs.
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, możesz zastosować strategię polegającą na umieszczeniu 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ć. Dostęp do interfejsu API uzyskujesz 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 przechowuje jedną odpowiedź HTTP, a metoda 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 obsługi.
Kiedy używać pamięci podręcznej
W swojej aplikacji internetowej możesz samodzielnie decydować, kiedy pliki mają być umieszczane w pamięci podręcznej. 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 umieszczać w pamięci podręcznej wszystkich komponentów naraz. Możesz to robić wielokrotnie w trakcie cyklu życia aplikacji internetowej, np.:
- podczas instalacji usługi w tle.
- Po pierwszym wczytaniu strony.
- Gdy użytkownik przejdzie do sekcji 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, aby 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 i nieprzezroczyste odpowiedzi dotyczące różnych domen
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. Podobnie jak inne zapisane w pamięci podręcznej zasoby, jest on dostępny tylko w źródle 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. Ponadto odpowiedzi nieprzezroczyste nie mają rzeczywistego rozmiaru w interfejsie Storage API, co wpływa 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 aplikacji w Narzędziach dla programistów. 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.