Strona główna / Artykuły

Projektowanie dla pamięci cache wstecznej/przód: warunki uczestnictwa, przywracanie i stan

Dowiedz się, w jaki sposób pamięć cache przeglądarki do cofania/przewijania przywraca całe strony, co ją w tle blokuje oraz jak radzić sobie ze stanem przywróconym za pomocą funkcji pageshow i pagehide.

Wydawca: REACTAPP.TOP14 min czytania3106 słów

Źródła: The Browser Feature Most Frontend Developers Completely Ignore

Gdy użytkownik naciska przycisk „Wstecz”, większość aplikacji w tle ponownie wykonywa operacje, których przeglądarka mogłaby uniknąć: ponowne pobieranie HTML, uruchamianie wszystkich skryptów, odbudowa struktury DOM oraz ponowne załadowanie danych. Pamięć cache do nawigacji wsteczno-przód (bfcache) została stworzona właśnie po to, by temu zapobiec, jednak codzienny kod często ją wyłącza bez żadnej reakcji użytkownika lub niewłaściwie obsługuje stronę, którą przywraca. Ten przewodnik wyjaśnia, w jaki sposób bfcache różni się od zwykłego cacheowania, jakie nawyki go blokują, jak wykryć i zareagować na przywróconą stronę oraz jak sprawdzić jej zachowanie na własnym ekranie.

Dlaczego nawigacja historią wymaga osobnej uwagi

Działania zmierzające do poprawy wydajności koncentrują się zazwyczaj na pierwszej wizycie użytkownika. Zespoły kompresują obrazy, dzielą pliki, wcześniej ładują czcionki, redukują koszty inicjalizacji strony, optymalizują wywołania API i obserwują czas najdłuższego renderowania treści. Wszystko to jest przydatne, ale zakłada w tle, że każda przeglądana strona zaczyna się od pustej karty i świeżo wpisanego adresu URL.

To nie jest sposób, w jaki ludzie przeglądają internet. Klient otwiera dany produkt, wraca do listy wyników, otwiera inny przedmiot i znów wraca. Czytelnik klika link z artykułu, a potem wraca, by go dokończyć. Ktoś ponownie otwiera nieukończony formularz. Przyciski „Wstecz” i „Dalej” należą do najczęściej używanych elementów sterujących we wszystkich przeglądarkach, a takie działania są standardowe, a nie wyjątkowe.

Przeglądarki optymalizują ten proces za pomocą bfcache. Zamiast usuwać stronę, gdy użytkownik odchodzi, przeglądarka może przechowywać w pamięci zrzut ekranu całego dokumentu. Gdy użytkownik wraca dzięki historii sesji, przeglądarka może pokazać ten zrzut ekranu zamiast powtarzać żądanie sieciowe, analizę HTML, wykonywanie skryptów, ładowanie danych i renderowanie. Każdy główny silnik przeglądarki implementuje jakąś wersję tego rozwiązania, chociaż dokładne zasady stosowania i mechanizmy wewnętrzne różnią się pomiędzy przeglądarkami.

Z perspektywy użytkownika udane przywrócenie wydaje się niemal natychmiastowe. Odstęp przewijania pozostaje taki sam jak wcześniej, DOM jest nienaruszony, pola form mogą nadal zawierać swoje wartości, a pamięć JavaScriptu po prostu kontynuuje pracę. Problem polega jednak na dwóch kwestiach: wiele zespołów nigdy nie sprawdza, czy ich strony spełniają odpowiednie warunki, a kod zakładający, że każda wizyta to zupełnie nowa strona, może zachowywać się niewłaściwie, gdy wraca stara.

Dlatego bfcache to coś więcej niż tylko darmowe przyspieszenie. Umożliwia ono bardziej realistyczne postrzeganie cyklu życia strony: strona może pozostać „uśpiona”, choć nadal istnieje, a potem się obudzić bez ponownego uruchamiania kodu startowego.

Jak bfcache różni się od cache’u HTTP

Wspólne słowo „cache” powoduje pierwsze zamieszanie. Łatwo założyć, że bfcache oznacza jedynie ponowne wykorzystanie CSS, skryptów, obrazów lub odpowiedzi API pobraanych wcześniej. To właśnie jest cache HTTP, który funkcjonuje na znacznie drobniejszym poziomie.

Kasza HTTP przechowuje pojedyncze odpowiedzi. Wrócenie na stronę może pozwolić przeglądarce pominąć niektóre pobierania, ale sam dokument nadal musi zostać odbudowany: HTML musi zostać zinterpretowany, skrypty wykonywane, framework uruchomiony, DOM stworzony, subskrypcje ponownie ustanowione i wysłane nowe żądania.

bfcache przechowuje całą stronę, w tym jej DOM oraz zbiór danych JavaScript. Gdy użytkownik przechodzi gdzie indziej, wykonywanie skryptów może zostać wstrzymane; gdy wraca przez historię przeglądania, przeglądarka pokazuje zachowaną stronę i kontynuuje jej wykonywanie. Dlatego trafienie do bfcache jest lepsze nawet od dobrze dostrojonego ponownego załadowania, które w dużej mierze pochodzi z kasy HTTP – po prostu pozostaje znacznie mniej pracy do wykonania.

To zmienia sposób, w jaki powinieneś myśleć o nawigacji. Podczas przywracania z bfcache twoja standardowa ścieżka uruchamiania nie musi być wykonywana ponownie. Zmienna na poziomie modułu może nadal przechowywać swoją wcześniejszą wartość. DOM nadal odzwierciedla to, co użytkownik zrobił przed opuszczeniem strony. Timery i inne operacje w czasie wykonywania programu kontynuują pracę od miejsca przerwy, zamiast być tworzone od zera.

Kod oparty na założeniu, że powrót zawsze oznacza pełne przeładowanie, może więc przegapić aktualizacje, utrzymywać na ekranie przestarzały stan lub tworzyć duplikaty, gdy próbuje skonfigurować coś, co już istnieje. Model myślowy, który należy przyjąć, jest prosty: przeglądarka nie ponownie wyrenderowała starej odpowiedzi HTML; przywróciła jedynie zawieszoną stronę.

Wielki sukces, który prawie nie wymaga nowego interfejsu

Większość ulepszeń wydajności wymaga jakichś widocznych kosztów: przeprojektowanych komponentów, nowych stanów ładowania, renderowania na serwerze lub innej strategii pobierania danych. bfcache jest nietypowy, ponieważ przeglądarka już implementuje ten mechanizm.

Pana zadaniem nie jest tworzenie własnego cache’u. Chodzi o unikanie blokowania możliwości korzystania przez przeglądarkę z tego, który już posiada, oraz o dostosowanie cyklu życia strony tak, by można ją było przywrócić.

Dzięki temu staje się to jedną z najskuteczniejszych optymalizacji dostępnych dla wielu zespołów. Strona przywrócona z pamięci unika powtarzających się transferów oraz większości operacji przetwarzania charakterystycznych dla zwykłej nawigacji. Korzyść jest największa na wolnych urządzeniach i sieciach, ale nawet szybkie komputery pokazują wyraźną różnicę pomiędzy ponownym budowaniem strony a jej prostym wyświetleniem.

Zachowuje również doświadczenie użytkownika, a nie tylko moment jego interakcji. Wyobraźmy sobie kogoś w połowie długiego artykułu, który otwiera powiązany link, a potem wraca. Tradycyjne ponowne załadowanie wymaga odbudowy strony, a następnie próby przywrócenia pozycji przewijania, często po tym, jak układ strony uległ zmianie. Restauracja danych z bfcache przywraca użytkownika niemal dokładnie w to samo miejsce.

Listy produktów jeszcze wyraźniej pokazują tę różnicę. Ktoś używa czterech lub pięciu filtrów, przegląda długą listę, wybiera konkretny produkt, a potem wraca. Jeśli lista pojawia się natychmiast w tym samym stanie, cała interakcja wydaje się ciągła. Jeśli natomiast strona zostanie ponownie załadowana, dane odświeżone, filtry usunięte lub strona wróci do pierwszego wiersza, strona wydaje się niestabilna, bez względu na to, jak dobre są jej wskaźniki podczas pierwszego załadowania.

Wydajność nie dotyczy tylko szybkości, z jaką użytkownicy mogą wejść do aplikacji. Dotyczy również tego, ile powtarzających się działań produkt pozwala im uniknąć podczas przemieszczania się między ekranami.

Jak nawyk usuwania treści w tle po cichu eliminuje te korzyści

Jednym z powodów, dla których bfcache jest pomijany, jest to, że nic nie widać wyraźnie nie działa, gdy strona nie spełnia określonych warunków. Przeglądarka po prostu wykonuje zwykłą nawigację w historii. Wszystko nadal funkcjonuje; użytkownicy po prostu tracą możliwość natychmiastowego przywrócenia stanu strony.

Klasycznym winowajcą jest zdarzenie unload. Starszy kod wykorzystuje je do wysyłania danych analitycznych, zwalniania zasobów lub informowania serwera o zamknięciu strony, wychodząc z założenia, że nawigacja zawsze niszczy stronę i daje ostatnią szansę na jej oczyszczenie.

Ta teoria już nie odpowiada rzeczywistości. Strona może zostać zawieszona w celu wykorzystania bfcache zamiast usunięta, a funkcja unload od dawna jest niewiarygodna, szczególnie w urządzeniach mobilnych, gdzie często w ogóle nie jest wywoływana. Zachowanie różni się pomiędzy przeglądarkami, ale rejestracja słuchacza unload może sprawić, że strona nie będzie kwalifikować się do przechowywania w bfcache w niektórych z nich. Obecne wytyczne platformy ostro odradzają używanie unload i zalecają wydarzenia cyklu życia odpowiadające nowoczesnemu modelowi. W chwili pisania Chrome również przechodzi proces deprecjacji unload, więc należy sprawdzić aktualną dokumentację przeglądarki w celu uzyskania najnowszych informacji.

Słuchacz nie musi nawet pochodzić z twojego kodu. Fragmenty analityczne, tagi reklamowe, widgety czatu wsparcia oraz starsze zależności czasami rejestrują takiego słuchacza wewnętrznie. Przechodzi on kontrolę kodu, ponieważ nie ma widocznego wpływu, a mimo to może usunąć optymalizację na poziomie przeglądarki przy każdej wizycie na tę stronę.

Zamiana funkcji unload nie polega na zmianie nazwy zdarzenia. Odpowiednia alternatywa zależy od tego, do czego faktycznie służy kod:

  • Dane analityczne można wysłać za pomocą navigator.sendBeacon() lub odpowiednio skonfigurowanego żądania fetch (na przykład z użyciem opcji keepalive) w momencie, gdy widoczność strony zmienia się na ukrytą.
  • Ostrzeżenia dotyczące niesoхранionych danych formularza mogą wykorzystywać funkcję beforeunload, ale taki słuchacz powinien być dodawany tylko wtedy, gdy istnieją niesoхранione zmiany, i usuwany po ich zapisaniu, a nie być przyłączony na cały okres istnienia strony.
  • Zasoby powiązane z aktywną stroną można wstrzymać i wznowić za pomocą eventów cyklu życia kompatybilnych z bfcache, o których mowa dalej.
  • Ważniejszy wniosek: opuszczenie strony nie oznacza końca jej życia. Kod oparty na takim założeniu okazuje się mniej niezawodny i wolniejszy, niż powinien być.

    Rozpoznawanie przywrócenia stanu za pomocą pageshow i pagehide

    Dwa zdarzenia otaczają ukryty okres. pagehide jest wyzwalane, gdy nawigacja usuwa dokument poza ekran, a pageshow – gdy nawigacja ponownie czyni dokument aktualnym, w tym po przywróceniu z bfcache. Oba zdarzenia zawierają właściwość persisted. W przypadku pageshow, wartość persisted jest true, gdy strona pochodzi z bfcache; w przypadku pagehide wskazuje to, że przeglądarka próbuje zachować stronę. W odróżnieniu od unload, pagehide został zaprojektowany tak, aby współistnieć z bfcache.

    Poniższy fragment pokazuje podstawowy kształt. Obsługa pageshow zwraca się wcześnie przy normalnym ładowaniu, więc logika odświeżania działa tylko wtedy, gdy przywraca się zachowana strona. Obsługa pagehide wstrzymuje połączenia w czasie rzeczywistym, gdy strona jest ukryta, niezależnie od tego, czy zostanie zapisana w pamięci cache. Funkcje pomocnicze są miejscami zastępczymi dla własnej logiki aplikacji.

    window.addEventListener("pageshow", (event) => {
      if (!event.persisted) {
        return;
      }
    
    refreshSessionState();
      refreshTimeSensitiveData();
    });
    
    window.addEventListener("pagehide", () => {
      pauseRealtimeConnections();
    });
    

    Zwróć uwagę na to, czego to nie robi: nie odświeża wszystkiego. Ponowne uruchamianie całej warstwy danych przy każdym przywróceniu zniweczyłoby większość korzyści. Celem jest odświeżanie tylko tych informacji, których poprawność może się istotnie zmienić podczas zawieszenia strony.

    To, co to oznacza, zależy od strony:

    • Główna strona z wiadomościami może chcieć wyszukać najnowsze nagłówki.
    • Ekran konta może potrzebować potwierdzenia, że sesja nie została zakończona w innej karcie.
  • Krok finalizacji zamówienia może wymagać ponownej weryfikacji stanu zapasów i cen.
  • Strona referencyjna z dokumentacją statyczną zazwyczaj może całkowicie pominąć logikę przywracania danych.
  • Prawdziwym ulepszeniem jest to, że aplikacja może teraz odróżnić nowe załadowanie od przywracania danych. Bez tej różnicy zespoły zwykle muszą wybierać między dwiema kiepskimi opcjami: nigdy nie odświeżać treści i narażać się na przestarzałe dane, albo ponownie wykonać pełną inicjalizację i poświęcić większość szybkości działania. Aplikacja, która rozumie mechanizm bfcache, traktuje proces przywracania jako odrębną fazę cyklu życia, zachowując to, co nadal jest ważne, i odświeżając to, czemu już nie można ufać.

    Gdy przywrócony stan staje się problemem poprawności

    Błyskawiczne przywracanie danych brzmi zupełnie pozytywnie, dopóki strona zapisana nie zawiera czegoś, co powinno już nie być wyświetlane.

    Rozważmy użytkownika, który otwiera panel konta, przechodzi na inną stronę, wylogowuje się z drugiej karty i w końcu naciska „Wstecz”. Przywrócony zrzut ekranu może nadal pokazywać informacje z wcześniejszej sesji. Przeglądarka nie narusza żadnej zasady bezpieczeństwa, pamiętając o stronie w ramach tej samej sesji przeglądania, ale twoja aplikacja może musieć sprawdzić, czy sesja jest nadal ważna, zanim pozwoli na dalszą interakcję.

    Dane czasowo zależne rodzą ten sam problem. Bilet mógł zostać kupiony w innej karcie, rekord edytowany przez kolegę lub okno dostępności mogło się zamknąć. Przywrócona strona może być doskonale wiernym obrazem przeszłości, a mimo to stanowić niewłaściwe źródło informacji w teraźniejszości.

    Powszechną reakcją jest całkowite wyłączenie buforowania. Zazwyczaj jest to zbyt radykalne rozwiązanie. Strona może zachować swój stan DOM i interakcji, odświeżając jedynie te dane, które muszą być aktualne, a pageshow to naturalne miejsce na dokonanie takiej synchronizacji. Oficjalne wytyczne jasno stwierdzają, że strony, których treść często się zmienia, mogą pobrać świeże dane po przywróceniu, zamiast całkowicie rezygnować z bfcache.

    Strony wymagające szczególnej ochrony przed zagrożeniami bezpieczeństwa nadal potrzebują świadomie opracowanych zasad buforowania i sesji, a sposób, w jaki przeglądarki traktują nagłówki takie jak Cache-Control: no-store, ulega zmianom. Chrome na przykład zaczął pozwalać niektórym stronom z flagą no-store na przechowywanie w bfcache, gdy spełnione są określone warunki. Unikaj prostych założeń dotyczących sposobu, w jaki każda przeglądarka obsługuje ten nagłówek, i sprawdzaj aktualną dokumentację przeglądarki przed poleganiem na niej.

    Bardziej bezpiecznym podejściem jest wyraźne określenie:

    • który stan może być bezpiecznie zachowany w takim samym stanie;
    • który stan musi zostać ponownie zweryfikowany po przywróceniu;
    • które działania użytkownika zawsze wymagają nowej weryfikacji uprawnień na serwerze, niezależnie od tego, co obecnie pokazuje interfejs.

    Ostatnia kategoria ma największe znaczenie. Klient może odświeżyć swoją widok, ale serwer nigdy nie powinien ufać przywróconej stronie jako dowodowi na to, że użytkownik nadal jest zalogowany.

    Zatrzymywanie długotrwałych połączeń podczas zawieszenia

    Połączenia otwarte, takie jak WebSockets, obsługi IndexedDB, blokady udostępnione oraz żądania w trakcie przetwarzania, komplikują funkcjonowanie bfcache, ponieważ przeglądarka musi zamrozić stronę, podczas gdy inne karty i dokumenty nadal działają. Zamrożona strona, która posiada blokadę udostępnioną lub otwarte połączenie do bazy danych, może przeszkadzać stronom, które są nadal aktywne. Zasady kwalifikacji różnią się pomiędzy przeglądarkami, a w niektórych przypadkach samo otwarte lub aktywne połączenie wystarcza, aby strona nie trafiła do pamięci cache. Zalecanym podejściem jest zwolnienie lub wstrzymanie takich zasobów, gdy strona jest ukryta, a następnie ich ostrożne przywrócenie, gdy stanie się widoczna.

    To nie oznacza konieczności usuwania każdego słuchacza zdarzeń lub obserwatora. Elementy, które znajdują się wyłącznie wewnątrz strony, takie jak słuchacze DOM, zazwyczaj mogą pozostać nieruchome bez żadnych konsekwencji. Należy skupić się natomiast na wszystkim, co wykracza poza zamarzniętą dokumentację do zewnętrznych systemów, lub na elementach, które nie powinny wyglądać na aktywne, gdy nikt nie przegląda strony.

    Naprzимер, panel sterowania w czasie rzeczywistym może zamknąć swoją sesję WebSocket w metodzie pagehide i otworzyć nową, gdy strona zostanie przywrócona. Implementacja musi chronić przed duplikatami, ponieważ zarówno standardowa ścieżka uruchamiania, jak i obsługa przywracania mogą próbować nawiązać połączenie; pojedyncza funkcja connect(), która sprawdza, czy połączenie już istnieje, to prosty sposób na zapewnienie jej idempotentności. Wrappery IndexedDB mogą zamknąć połączenie z bazą danych przed zawieszeniem i ponownie je otworzyć w momencie potrzeby.

    Ta dyscyplina przynosi korzyści nie tylko w kontekście bfcache. Zmusza zespół do ustalenia, kto jest odpowiedzialny za każdy zasób zewnętrzny, kiedy powinien istnieć oraz co się dzieje, gdy dokument staje się nieaktywny. Takie umowy są równie ważne w przypadku kart w tle, urządzeń mobilnych, które zamykają strony, oraz przerwanych sesji.

    Aplikacje jednostronicowe nadal odnoszą korzyści

    bfcache działa przy nawigacji pomiędzy dokumentami zarządzanymi przez przeglądarkę. Zmiany tras obsługiwane w JavaScript, przy których nie ładowany jest nowy dokument, pozostają poza jego zakresem. Przejście z /products na /products/42 za pośrednictwem routera po stronie klienta to nadal coś, co aplikacja jednostronicowa i jej framework zarządzają samodzielnie.

    Mimo to SPA mają wiele do zyskania. Użytkownicy regularnie opuszczają takie aplikacje, by przejść na osobną stronę, stronę third-party, usługę logowania lub zupełnie inną aplikację, a później wracać. W takim przypadku przeglądarka może przywrócić całą aplikację zamiast ponownie pobierać pliki, przerysowywać każdy komponent i uruchamiać procedury konfiguracji od nowa. Oficjalne wytyczne jasno wskazują na tę korzyść, zauważając jednocześnie, że zmiany tras wewnątrz aplikacji są poza kontrolą bfcache.

    Takie powroty mogą ujawnić założenia na poziomie frameworka:

    • przypuszczenie, że inicjalizacja root ma odbywać się za każdym razem, gdy dokument staje się widoczny;
    • warstwa danych zakładająca, że jej cache zawsze jest pusty;
    • połączenie w czasie rzeczywistym tworzone na nowo, podczas gdy stare nadal jest przywracane;
    • komponent wyświetlający dane, które były poprawne w momencie opuszczenia aplikacji i które teraz mogą być przestarzałe.

    Żaden framework nie ukrywa własnego cyklu życia przeglądarki. Niezależnie od tego, czy używasz React, Vue, Angular czy Svelte, kod nadal jest wykonywany w ramach dokumentu, który przeglądarka może zachować i przywrócić. Framework dobrze radzi sobie z organizacją stanu, ale nie ma możliwości oceny za ciebie, które dane biznesowe są nadal ważne po przerwaniu działania. W React na przykład komponenty nie są ponownie montowane po przywróceniu bfcache, więc efekty uruchomione podczas montowania nie zostaną wykonyane ponownie; to słuchacz pageshow pozwala aplikacji dowiedzieć się, że upłynął czas.

    Wielu deweloperów front-endu znacznie lepiej zna zachowanie montowania i demontowania w swoim frameworku niż cykl życia dokumentu przeglądarki. bfcache pokazuje, że montowanie i demontowanie opisują jedynie jeden aspekt tego, co faktycznie dzieje się z stroną.

    Testowanie bfcache w kilka minut

    bfcache pozostaje ignorowany po części dlatego, że trudno jest stwierdzić, czy faktycznie działa. Powrót na stronę może już wydawać się szybki, a panel Sieci niewiele pomaga, ponieważ przywrócona strona całkowicie omija zwykłą sekwencję żądań.

    Chrome DevTools zawiera specjalnie stworzoną funkcję sprawdzania bfcache, dostępną w panelu Aplikacje. Uruchamiasz ją, Chrome przegląda stronę i wraca na nią, a narzędzie informuje, czy strona została przywrócona. Gdy strona nie spełnia warunków, DevTools wymienia konkretne przyczyny i wskazuje, które ramki są za to odpowiedzialne.

    Należy włączyć tę funkcję do regularnych badań wydajności ważnych stron, szczególnie wyników wyszukiwania, artykułów, list produktów, paneli sterowania oraz wszelkich ekranów, które użytkownicy często odwiedzają. Uruchamiaj ją również z włączonymi skryptami od third party, ponieważ spełnienie warunków jest często blokowane przez kod znajdujący się poza twoim własnym plikiem.

    Dla danych z pola, informacja notRestoredReasons udostępniana przez API Performance (w pozycji dotyczącej czasu nawigacji) może wyjaśnić, dlaczego rzeczywiste nawigacje w historii nie zostały przywrócone. Ta funkcja nie jest dostępna we wszystkich przeglądarkach, więc należy do niej podchodzić jako do narzędzia pomocniczego, a nie jako czegoś, od czego zależy działanie kodu we wszystkich przeglądarkach. Mimo to jest ona cenna, ponieważ żaden test lokalny nie może odtworzyć każdej rozszerzenia przeglądarki, iframe od strony trzeciej, otwartej połączenia, nagłówka ani innej warunku przeglądarki, które mogą mieć użytkownicy. Lekką alternatywą jest rejestrowanie wartości event.persisted z wydarzenia pageshow w systemie analitycznym, aby zmierzyć rzeczywisty wskaźnik odwiedzin.

    Nie oczekuj, że każda nawigacja w historii będzie przechowywana w pamięci cache. Przeglądarki usuwają takie zapisy w celu zarządzania pamięcią, a niektóre bariery znajdują się poza kontrolą strony. Realistycznym celem jest usunięcie tych bariér, których można uniknąć, oraz prawidłowe radzenie sobie z przywracaniem stanu w momencie, gdy to się zdarzy.

    Podsumowanie

    bfcache łatwo przeoczyć właśnie dlatego, że nic w twojej bazie kodu go nie aktywuje. Nie ma żadnego pakietu, komponentu ani pliku konfiguracyjnego, które sprawiałyby, że wyglądałby on jak część architektury; przeglądarka po prostu stara się zapewnić użytkownikom lepsze doświadczenie. Ta niewidzialność ma dwa aspekty: gdy funkcjonuje prawidłowo, użytkownicy mogą korzystać z niemal natychmiastowej nawigacji w historii przy prawie zerowym nakładzie kodu; gdy zostanie zablokowany, strona zwalnia bez żadnego błędu; a gdy przywracanie stanu nie przebiega prawidłowo, pojawia się stary stan, ponieważ aplikacja zakładała, że powrót zawsze oznacza ponowne załadowanie.

    Praktyczna lista kontrolna dla najczęściej odwiedzanych stron:

    • Usuń słuchacze unload, w tym te dodane przez skrypty stron trzecich, i przenieś ich funkcjonalność do pagehide, visibilitychange lub sendBeacon().
    • Dołącz beforeunload tylko wtedy, gdy istnieją niesalwowane zmiany.
    • Zamknij lub wstrzymaj połączenia zewnętrzne w momencie pagehide i ponownie nawiąż je w sposób idempotentny po przywróceniu strony.
    • Użyj pageshow w połączeniu z event.persisted, aby odświeżyć tylko te dane, które mogą stać się przestarzałe, i zachowaj sprawdzanie uprawnień na serwerze.
    • Zrób test pamięci cache w Narzędziach deweloperskich i śledź rzeczywiste tempo przywracania danych tam, gdzie API na to pozwalają.

    Zasadnicza zmiana dotyczy sposobu postrzegania strony. Zamiast pojedynczej prostej linii od stworzenia do zniszczenia, jej żywot może obejmować konfigurację, ukrywanie, zamrożenie, przywrócenie, synchronizację i kontynuację działania. Zespoły wkładają wiele wysiłku w przyspieszenie rekonstrukcji strony, podczas gdy przeglądarka często jest gotowa całkowicie pominąć tę rekonstrukcję i zwrócić użytkownikom stronę, którą już mieli.