Obsługa przeglądarek
Nowoczesne przeglądarki czasami zawieszają strony lub całkowicie je odrzucają, gdy zasoby systemowe są ograniczone. W przyszłości przeglądarki chcą to robić proaktywnie, więc zużywają mniej energii i pamięci. Interfejs API cyklu życia strony udostępnia elementy cyklu życia, dzięki którym strony mogą bezpiecznie obsługiwać interwencje przeglądarki bez wpływu na komfort użytkownika. Zapoznaj się z interfejsem API, aby sprawdzić, czy warto wdrożyć te funkcje w aplikacji.
Tło
Cykl życia aplikacji to kluczowy sposób, w jaki nowoczesne systemy operacyjne zarządzają zasobami. Na Androidzie, iOS i w najnowszych wersjach Windowsa aplikacje mogą być uruchamiane i zatrzymywane w dowolnym momencie przez system operacyjny. Dzięki temu platformy mogą optymalizować i przydzielać zasoby tam, gdzie są najbardziej korzystne dla użytkownika.
W internecie nie było do tej pory takiego cyklu życia, a aplikacje mogą działać w nieskończoność. W przypadku dużej liczby wczytanych stron internetowych może dojść do nadmiernego wykorzystania ważnych zasobów systemu, takich jak pamięć, procesor, bateria i sieć, co może negatywnie wpłynąć na wrażenia użytkowników.
Platforma internetowa od dawna zawierała zdarzenia związane ze stanami cyklu życia, takie jak load
, unload
i visibilitychange
. Jednak te zdarzenia umożliwiają deweloperom reagowanie tylko na zmiany stanu cyklu życia zainicjowane przez użytkownika. Aby internet działał niezawodnie na urządzeniach o małej mocy (i ogólnie był bardziej oszczędny pod względem zasobów) przeglądarki muszą mieć możliwość proaktywnego odzyskiwania i przeznaczania zasobów systemowych.
W rzeczywistości przeglądarki już teraz podejmują aktywne działania w celu oszczędzania zasobów na stronach na kartach w tle, a wiele przeglądarek (zwłaszcza Chrome) chciałoby robić to jeszcze bardziej, aby zmniejszyć ogólne zużycie zasobów.
Problem polega na tym, że programiści nie są w stanie przygotować się na tego typu interwencje inicjowane przez system, a nawet nie wiedzą, że mają miejsce. Oznacza to, że przeglądarki muszą być zachowawcze, aby nie uszkodzić stron internetowych.
Interfejs Page Lifecycle API próbuje rozwiązać ten problem, wykonując te czynności:
- Wprowadzenie i standaryzacja koncepcji stanów cyklu życia w internecie.
- Definiowanie nowych stanów inicjowanych przez system, które umożliwiają przeglądarkom ograniczanie zasobów, z których mogą korzystać ukryte lub nieaktywne karty.
- Tworzenie nowych interfejsów API i zdarzeń, które umożliwiają deweloperom stron internetowych reagowanie na przejścia do i z tych nowych stanów inicjowanych przez system.
Rozwiązanie to zapewnia przewidywalność dla twórców aplikacji internetowych, które są odporne na interwencje systemowe. Umożliwia też przeglądarkom bardziej agresywną optymalizację zasobów systemowych, co w efekcie korzystnie wpływa na wszystkich użytkowników internetu.
W dalszej części tego posta omówimy nowe funkcje cyklu życia strony oraz omówimy ich związek ze wszystkimi stanami i zdarzeniami na platformie internetowej. Zawiera on również rekomendacje i sprawdzone metody dotyczące rodzajów prac, które deweloperzy powinni (lub nie powinni) wykonywać w każdym stanie.
Omówienie stanów cyklu życia strony i zdarzeń
Wszystkie stany cyklu życia strony są oddzielne i wykluczają się wzajemnie, co oznacza, że strona może znajdować się tylko w jednym stanie w danym momencie. Większość zmian stanu cyklu życia strony można zazwyczaj obserwować na podstawie zdarzeń DOM (wyjątki znajdziesz w zaleceniach dewelopera dla każdego stanu).
Najłatwiej wyjaśnić stany cyklu życia strony oraz zdarzenia sygnalizujące przejścia między nimi za pomocą diagramu:
Stany
Tabela poniżej zawiera szczegółowe informacje o każdym stanie. Raport zawiera również listę możliwych stanów, które mogą wystąpić przed i po, oraz zdarzeń, za pomocą których deweloperzy mogą obserwować zmiany.
Stan | Opis |
---|---|
Aktywne |
Strona jest w stanie aktywny, jeśli jest widoczna i ma fokus wprowadzania danych.
Możliwe stany poprzednie: |
Pasywna |
Strona jest w stanie pasywnym, jeśli jest widoczna i nie ma aktywnego pola wprowadzania danych.
Możliwe stany poprzednie:
Możliwe następne stany: |
Ukryta |
Strona jest w stanie ukrytej, jeśli nie jest widoczna (i nie została zamrożona, odrzucona ani zakończona).
Możliwe stany poprzednie:
Możliwe następne stany: |
Zablokowany |
W stanie zamrożonej przeglądarka wstrzymuje wykonywanie
zadań w
kolejkach zadań strony do momentu odmrożenia strony. Oznacza to, że takie elementy jak liczniki czasu JavaScript i wywołania zwrotne pobierania nie są uruchamiane. Zadania, które są już wykonywane, mogą się zakończyć (przede wszystkim wywołanie Przeglądarki blokują strony, aby zmniejszyć wykorzystanie procesora, baterii i danych, a także aby przyspieszyć przechodzenie wstecz i do przodu, unikając ponownego wczytywania całej strony.
Możliwe stany poprzednie:
Możliwe następne stany: |
Zakończona |
Strona jest w stanie zakończenia w momencie rozpoczęcia wyładowywania i czyszczenia z pamięci przez przeglądarkę. W tym stanie nie można uruchamiać nowych zadań, a trwająco wykonywane zadania mogą zostać przerwane, jeśli trwają zbyt długo.
Możliwe stany poprzednie:
Możliwe następne stany: |
Odrzucona |
Gdy przeglądarka wyładuje stronę, aby oszczędzać zasoby, strona jest w stanie odrzucona. W tym stanie nie można uruchamiać żadnych zadań, wywołań zwrotnych zdarzeń ani JavaScriptu, ponieważ odrzucenia zazwyczaj występują w przypadku ograniczeń zasobów, gdzie nie można uruchomić nowych procesów. W stanie odrzuconej karta (w tym jej tytuł i ikona) jest zwykle widoczna dla użytkownika, nawet jeśli strona została zamknięta.
Możliwe stany poprzednie:
Możliwe kolejne stany: |
Wydarzenia
Przeglądarki wysyłają wiele zdarzeń, ale tylko niewielka ich część sygnalizuje możliwą zmianę stanu cyklu życia strony. Tabela poniżej zawiera wszystkie zdarzenia związane z cyklem życia oraz stany, między którymi mogą się one przełączać.
Nazwa | Szczegóły |
---|---|
focus
|
Element DOM został zaznaczony.
Uwaga: zdarzenie
Możliwe poprzednie stany:
Możliwe stany bieżące: |
blur
|
Element DOM utracił fokus.
Uwaga: zdarzenie
Możliwe stany poprzednie:
Możliwe stany bieżące: |
visibilitychange
|
Wartość
|
freeze
*
|
Strona została właśnie zablokowana. Żadne zadania zablokowane w kolejkach zadań na stronie nie zostaną uruchomione.
Możliwe stany poprzednie:
Możliwe bieżące stany: |
resume
*
|
Przeglądarka wznowiła działanie zablokowanej strony.
Możliwe stany poprzednie:
Możliwe stany bieżące: |
pageshow
|
Przechodzimy do wpisu z historii sesji. Może to być zupełnie nowa strona lub strona pobrana z pamięci podręcznej. Jeśli strona została pobrana z pamięci podręcznej stanu strony internetowej, właściwość
Możliwe stany poprzednie: |
pagehide
|
Przechodzimy z poziomu wpisu z historii sesji. Jeśli użytkownik przechodzi na inną stronę i przeglądarka może dodać bieżącą stronę do pamięci podręcznej stanu strony internetowej, aby użyć jej później, właściwość
Możliwe stany poprzednie:
Możliwe bieżące stany: |
beforeunload
|
Okno, dokument i jego zasoby zostaną usunięte z pamięci. Dokument jest nadal widoczny, a wydarzenie można jeszcze anulować.
Ważne: zdarzenie
Możliwe poprzednie stany:
Możliwe aktualne stany: |
unload
|
Trwa wyładowywanie strony.
Ostrzeżenie: używanie zdarzenia
Możliwe poprzednie stany:
Możliwe stany bieżące: |
* Wskazuje nowe zdarzenie zdefiniowane przez interfejs Page Lifecycle API.
Nowe funkcje dodane w Chrome 68
Poprzedni wykres przedstawia 2 stany, które są inicjowane przez system, a nie przez użytkownika: zablokowano i odrzucone. Jak już wspomnieliśmy, przeglądarki już teraz czasami zawieszają i zamykają ukryte karty (według własnego uznania), ale deweloperzy nie mają możliwości sprawdzenia, kiedy to się dzieje.
W Chrome 68 deweloperzy mogą teraz obserwować, kiedy ukryta karta jest zablokowana i odblokowana, na podstawie zdarzeń freeze
i resume
w document
.
document.addEventListener('freeze', (event) => {
// The page is now frozen.
});
document.addEventListener('resume', (event) => {
// The page has been unfrozen.
});
Od wersji 68 w Chrome na komputery obiekt document
zawiera teraz właściwość wasDiscarded
(w tym zgłoszeniu śledzimy obsługę Androida). Aby sprawdzić, czy strona została odrzucona, gdy karta była ukryta, możesz sprawdzić wartość tej właściwości podczas wczytywania strony (uwaga: aby ponownie użyć odrzuconej strony, musisz ją ponownie załadować).
if (document.wasDiscarded) {
// Page was previously discarded by the browser while in a hidden tab.
}
Wskazówki dotyczące ważnych czynności w przypadku zdarzeń freeze
i resume
, a także informacje o tym, jak obsługiwać i przygotowywać strony do odrzucenia, znajdziesz w rekomendacjach dla programistów dotyczących każdego stanu.
W kolejnych sekcjach omawiamy, jak te nowe funkcje pasują do istniejących stanów i zdarzeń platformy internetowej.
Jak obserwować stany cyklu życia strony w kodzie
W stanach active (aktywny), passive (bierny) i hidden (ukryty) można uruchamiać kod JavaScript, który określa bieżący stan cyklu życia strony za pomocą istniejących interfejsów API platformy internetowej.
const getState = () => {
if (document.visibilityState === 'hidden') {
return 'hidden';
}
if (document.hasFocus()) {
return 'active';
}
return 'passive';
};
Stany zamrożone i zakończone można natomiast wykryć tylko w odpowiednich detektorówach zdarzeń (freeze
i pagehide
), ponieważ stany te się zmieniają.
Jak obserwować zmiany stanu
Korzystając z zdefiniowanej wcześniej funkcji getState()
, możesz obserwować wszystkie zmiany stanu cyklu życia strony za pomocą poniższego kodu.
// Stores the initial state using the `getState()` function (defined above).
let state = getState();
// Accepts a next state and, if there's been a state change, logs the
// change to the console. It also updates the `state` value defined above.
const logStateChange = (nextState) => {
const prevState = state;
if (nextState !== prevState) {
console.log(`State change: ${prevState} >>> ${nextState}`);
state = nextState;
}
};
// Options used for all event listeners.
const opts = {capture: true};
// These lifecycle events can all use the same listener to observe state
// changes (they call the `getState()` function to determine the next state).
['pageshow', 'focus', 'blur', 'visibilitychange', 'resume'].forEach((type) => {
window.addEventListener(type, () => logStateChange(getState()), opts);
});
// The next two listeners, on the other hand, can determine the next
// state from the event itself.
window.addEventListener('freeze', () => {
// In the freeze event, the next state is always frozen.
logStateChange('frozen');
}, opts);
window.addEventListener('pagehide', (event) => {
// If the event's persisted property is `true` the page is about
// to enter the back/forward cache, which is also in the frozen state.
// If the event's persisted property is not `true` the page is
// about to be unloaded.
logStateChange(event.persisted ? 'frozen' : 'terminated');
}, opts);
Ten kod ma trzy zadania:
- Ustawia stan początkowy za pomocą funkcji
getState()
. - Definiuje funkcję, która przyjmuje następny stan i w razie zmiany rejestruje zmiany stanu w konsoli.
- Dodaje metody odbierające zdarzenia dla wszystkich niezbędnych zdarzeń cyklu życia, które z kolei wywołują metodę
logStateChange()
, przekazując jej następny stan.
W kodzie należy zwrócić uwagę na to, że wszystkie detektory zdarzeń są dodawane do window
i wszystkie są przekazywane do {capture: true}
.
Dzieje się tak z kilku przyczyn:
- Nie wszystkie zdarzenia z cyklu życia strony mają ten sam cel.
pagehide
ipageshow
są wywoływane w elementachwindow
;visibilitychange
,freeze
iresume
są wywoływane w elementachdocument
, afocus
iblur
są wywoływane w odpowiednich elementach DOM. - Większość z nich nie powoduje przenoszenia zdarzeń, co oznacza, że nie można dodać do wspólnego elementu przodka detektorów zdarzeń nieprzechwytujących i obserwować wszystkich zdarzeń.
- Faza przechwytywania jest wykonywana przed fazą celu lub bąbelka, dlatego dodanie w niej detektorów pomaga zapewnić ich uruchomienie, zanim inny kod je anuluje.
Zalecenia dla deweloperów w przypadku każdego stanu
Jako programiści powinniście znać stany cyklu życia strony oraz wiedzieć, jak je sprawdzać w kodzie, ponieważ rodzaj działań, które należy wykonywać (lub nie), zależy w dużej mierze od stanu strony.
Nie ma sensu wyświetlanie użytkownikowi powiadomienia przejściowego, jeśli strona jest ukryta. Chociaż ten przykład jest dość oczywisty, warto wymienić inne, mniej oczywiste rekomendacje.
Stan | Rekomendacje dla deweloperów |
---|---|
Active |
Stan aktywny to czas o najwyższym znaczeniu dla użytkownika, a tym samym najważniejszy czas na reagowanie na dane wejściowe użytkownika. Wszystkie zadania wykonywane poza interfejsem, które mogą blokować wątek główny, powinny mieć priorytet okresów bezczynności lub przeciążone skryptem webowym. |
Passive |
W stanie pasywnym użytkownik nie wchodzi w interakcję ze stroną, ale nadal może ją widzieć. Oznacza to, że animacje i aktualizacje interfejsu powinny przebiegać płynnie, ale czas ich trwania nie jest tak istotny. Gdy strona zmieni stan z aktywnej na bierną, warto zapisać niezapisane stany aplikacji. |
Gdy strona zmieni stan z biernego na ukryty, użytkownik może nie wchodzić z nią w interakcję, dopóki nie zostanie ona ponownie załadowana. Przejście do stanu ukryte jest też często ostatnią zmianą stanu, którą deweloperzy mogą niezawodnie zaobserwować (szczególnie na urządzeniach mobilnych, ponieważ użytkownicy mogą zamykać karty lub całą aplikację przeglądarki, a w takich przypadkach nie są wywoływane zdarzenia Oznacza to, że stan ukryty należy traktować jako prawdopodobny koniec sesji użytkownika. Inaczej mówiąc, zachować niezapisane stany aplikacji i wysłać niezasłane dane analityczne. Powinieneś też przestać aktualizować interfejs (ponieważ użytkownik nie będzie widzieć tych zmian) i zatrzymać wszystkie zadania, których użytkownik nie chce wykonywać w tle. |
|
Frozen |
W stanie zamrożonej strony zadania podlegające zamrożeniu w kolejkach zadań są zawieszone do czasu odblokowania strony, co może nigdy nie nastąpić (np. jeśli strona zostanie odrzucona). Oznacza to, że gdy strona zmieni się z ukrytej na zablokowaną, konieczne będzie zatrzymanie liczników czasu lub zerwanie wszystkich połączeń, które w przypadku zablokowania mogą mieć wpływ na inne otwarte karty w tym samym pochodzeniu lub uniemożliwić przeglądarce umieszczenie strony w pamięci podręcznej stanu strony internetowej. W szczególności ważne jest, aby:
Musisz też zachować stan dynamicznego widoku (np. pozycję przewijania w nieskończonej liście) w Jeśli strona zmieni stan z zamrożonego na ukryty, możesz ponownie otworzyć zamknięte połączenia lub wznowić przerwane wywołania, które zostały zatrzymane, gdy strona była zamrożona. |
Terminated |
Zwykle nie musisz podejmować żadnych działań, gdy strona przejdzie w stan zakończony. Strony, które są wyładowywane w wyniku działania użytkownika, zawsze przechodzą przez stan ukryty, zanim staną się stanem zakończony. W stanie ukrytym powinna być wykonywana logika kończenia sesji (np. zapisywanie stanu aplikacji i raportowanie do Analytics). Oprócz tego (jak wspomnieliśmy w zaleceniach dotyczących stanu ukrytego) deweloperzy muszą zdawać sobie sprawę, że w wielu przypadkach (zwłaszcza na urządzeniach mobilnych) nie można prawidłowo wykryć przejścia w stan zakończony.Dlatego deweloperzy, którzy polegają na zdarzeniach zakończenia (np. |
Discarded |
Deweloperzy nie mogą zauważyć stanu wyrzucony w momencie, gdy strona zostaje wyrzucona. Dzieje się tak, ponieważ strony są zazwyczaj odrzucane z powodu ograniczeń zasobów, a w większości przypadków odblokowanie strony tylko po to, aby umożliwić uruchomienie skryptu w odpowiedzi na zdarzenie odrzucenia, jest po prostu niemożliwe. W związku z tym musisz się przygotować na możliwość odrzucenia zmiany z ukrytej na zamrożoną. Następnie możesz zareagować na przywrócenie odrzuconej strony podczas jej wczytywania, zaznaczając |
Ponieważ niezawodność i kolejność zdarzeń cyklu życia nie są konsekwentnie wdrażane we wszystkich przeglądarkach, najłatwiej jest postępować zgodnie z zaleceniami w tabeli, używając pliku PageLifecycle.js.
Starsze interfejsy API cyklu życia, których należy unikać
Poniższe zdarzenia należy unikać, gdy tylko jest to możliwe.
Zdarzenie wyładowania
Wielu deweloperów traktuje zdarzenie unload
jako gwarantowane wywołanie zwrotne i używa go jako sygnału zakończenia sesji do zapisywania stanu i wysyłania danych analitycznych, ale jest to bardzo zawodne, zwłaszcza w przypadku urządzeń mobilnych. Zdarzenie unload
nie jest wywoływane w wielu typowych sytuacjach rozładowania, np. przy zamykaniu karty w przełączniku kart na urządzeniu mobilnym lub zamykaniu aplikacji przeglądarki w przełączniku aplikacji.
Dlatego zawsze lepiej jest polegać na zdarzeniu visibilitychange
, aby określić, kiedy kończy się sesja, i uznać stan ukryty za ostatni niezawodny moment zapisywania danych aplikacji i użytkowników.
Poza tym sama obecność zarejestrowanego modułu obsługi zdarzeń unload
(za pomocą onunload
lub addEventListener()
) może uniemożliwić przeglądarkom umieszczanie stron w pamięci podręcznej stanu strony internetowej, aby przyspieszyć ładowanie wstecz i do przodu.
We wszystkich nowoczesnych przeglądarkach zalecamy zawsze używać zdarzenia pagehide
, aby wykrywać możliwe wyładowania strony (czyli stan zakończony), zamiast zdarzenia unload
. Jeśli musisz obsługiwać Internet Explorera w wersji 10 i starszych, włącz wykrywanie zdarzenia pagehide
i używaj unload
tylko wtedy, gdy przeglądarka nie obsługuje pagehide
:
const terminationEvent = 'onpagehide' in self ? 'pagehide' : 'unload';
window.addEventListener(terminationEvent, (event) => {
// Note: if the browser is able to cache the page, `event.persisted`
// is `true`, and the state is frozen rather than terminated.
});
Zdarzenie beforeunload
Zdarzenie beforeunload
ma podobny problem do zdarzenia unload
, ponieważ w przeszłości obecność zdarzenia beforeunload
mogła uniemożliwić stronom kwalifikowanie się do korzystania z pamięci podręcznej stanu strony internetowej. Nowoczesne przeglądarki nie mają tego ograniczenia. Niektóre przeglądarki nie wywołują zdarzenia beforeunload
, gdy próbują umieścić stronę w pamięci podręcznej wstecz/wprzód, co oznacza, że to zdarzenie nie jest wiarygodnym sygnałem końca sesji.
Dodatkowo niektóre przeglądarki (w tym Chrome) wymagają interakcji użytkownika ze stroną, zanim pozwolą na wywołanie zdarzenia beforeunload
, co dodatkowo wpływa na jego niezawodność.
Jedną z różnic między beforeunload
a unload
jest to, że beforeunload
może być używany w legalnych celach. Możesz na przykład ostrzec użytkownika, że jeśli będzie kontynuować wylogowywanie, utraci niezapisane zmiany.
Ponieważ istnieją uzasadnione powody, dla których warto używać beforeunload
, zalecamy tylko dodawanie odbiorców beforeunload
, gdy użytkownik ma niezapisane zmiany, a następnie usuwanie ich natychmiast po zapisaniu.
Inaczej mówiąc, nie rób tego (ponieważ bezwarunkowo dodajesz listenera beforeunload
):
addEventListener('beforeunload', (event) => {
// A function that returns `true` if the page has unsaved changes.
if (pageHasUnsavedChanges()) {
event.preventDefault();
// Legacy support for older browsers.
return (event.returnValue = true);
}
});
Zamiast tego użyj tego kodu (ponieważ dodaje on parametr beforeunload
listener tylko wtedy, gdy jest to potrzebne, a usuwanie go, gdy nie jest to konieczne):
const beforeUnloadListener = (event) => {
event.preventDefault();
// Legacy support for older browsers.
return (event.returnValue = true);
};
// A function that invokes a callback when the page has unsaved changes.
onPageHasUnsavedChanges(() => {
addEventListener('beforeunload', beforeUnloadListener);
});
// A function that invokes a callback when the page's unsaved changes are resolved.
onAllChangesSaved(() => {
removeEventListener('beforeunload', beforeUnloadListener);
});
Najczęstsze pytania
Dlaczego nie ma stanu „wczytywanie”?
Interfejs Page Lifecycle API określa stany, które są dyskretne i wzajemnie się wykluczają. Strona może być wczytana w stanie aktywnym, biernym lub ukrytym, a przed zakończeniem wczytywania może zmienić stan lub zostać zamknięta. W ramach tej zasady oddzielny stan wczytywania nie ma sensu.
Moja strona wykonuje ważne zadania, gdy jest ukryta. Jak mogę zapobiec jej zamrożeniu lub odrzuceniu?
Istnieje wiele uzasadnionych powodów, dla których strony internetowe nie powinny być zamrażane podczas działania w stanie ukrytym. Najbardziej oczywistym przykładem jest aplikacja odtwarzająca muzykę.
Są też sytuacje, w których odrzucenie strony przez Chrome byłoby ryzykowne, na przykład gdy zawiera ona formularz z nieprzesłanymi danymi użytkownika lub gdy ma element beforeunload
, który ostrzega o usuwaniu strony.
Na razie Chrome będzie ostrożnie odrzucać strony i robić to tylko wtedy, gdy będzie mieć pewność, że nie wpłynie to na użytkowników. Na przykład strony, które w stanie ukrytym mają wykonać jedną z tych czynności, nie zostaną odrzucone, chyba że zasoby będą skrajnie ograniczone:
- Odtwarzanie dźwięku
- Korzystanie z WebRTC
- Aktualizowanie tytułu tabeli lub jej ikony
- Wyświetlanie alertów
- Wysyłam powiadomienia push
Listę bieżących funkcji służących do określania, czy kartę można bezpiecznie zablokować lub odrzucić, znajdziesz w sekcji Heurystyka do zawieszania i odrzucania w Chrome.
Co to jest pamięć podręczna stanu strony internetowej?
Pamięć podręczna stanu strony internetowej to termin opisujący optymalizację nawigacji w niektórych przeglądarkach, która przyspiesza korzystanie z przycisków Wstecz i Dalej.
Gdy użytkownik opuści stronę, przeglądarki tego typu blokują jej wersję, aby można było ją szybko wznowić, nawet jeśli użytkownik wróci za pomocą przycisków Wstecz lub Dalej. Pamiętaj, że dodanie modułu obsługi zdarzeń unload
uniemożliwia wykonanie tej optymalizacji.
W praktyce zamrażanie jest takie samo jak zamrażanie przeglądarek w celu oszczędzania procesora lub baterii. Z tego powodu jest to uważane za część stanu cyklu życia zamrożonego.
Jak mogę zapisać dane w IndexedDB, jeśli nie mogę uruchomić asynchronicznych interfejsów API w stanie zawieszenia lub zakończenia?
W stanach zablokowanych lub zakończonych zablokowane zadania w kolejkach zadań na stronie są zawieszane, co oznacza, że nie można w niezawodny sposób korzystać z interfejsów API asynchronicznych i opartych na wywołaniach zwrotnych, takich jak IndexedDB.
W przypadku kodu, który musi działać już teraz, deweloperzy mają 2 opcje:
- Używanie pamięci sesji: pamięć sesji działa synchronicznie i zapisuje dane po odrzuceniu strony.
- Użyj metody IndexedDB z skryptu service worker: skrypt service worker może przechowywać dane w IndexedDB po zamknięciu lub odrzuceniu strony. W detektorze zdarzeń
freeze
lubpagehide
możesz wysłać dane do skryptu service worker za pomocąpostMessage()
, który może zająć zapisywanie danych.
Testowanie aplikacji w zamrożonym i odrzuconym stanie
Aby sprawdzić, jak aplikacja zachowuje się w zamrożonym i odrzuconym stanie, możesz kliknąć chrome://discards
, aby zamrozić lub odrzucić dowolną otwartą kartę.
Dzięki temu możesz mieć pewność, że Twoja strona prawidłowo obsługuje zdarzenia freeze
i resume
, a także flagę document.wasDiscarded
podczas ponownego wczytywania stron po odrzuceniu.
Podsumowanie
Deweloperzy, którzy chcą korzystać z zasobów systemowych urządzeń użytkowników, powinni tworzyć aplikacje z myślą o stanach cyklu życia strony. Ważne jest, aby strony internetowe nie zużywały nadmiernych zasobów systemowych w sytuacjach, których użytkownik nie przewidział.
Im więcej deweloperów zacznie wdrażać nowe interfejsy API cyklu życia strony, tym bezpieczniejsze będzie blokowanie i odrzucanie nieużywanych stron przez przeglądarki. Oznacza to, że przeglądarki będą zużywać mniej pamięci, procesora, baterii i zasobów sieciowych, co jest korzystne dla użytkowników.