Interfejs Page Lifecycle API

Obsługa przeglądarek

  • Chrome: 68.
  • Krawędź: 79.
  • Firefox: funkcja nieobsługiwana.
  • Safari: nieobsługiwane.

Nowoczesne przeglądarki czasami zawieszają lub odrzucają strony, zasoby systemowe są ograniczone. W przyszłości przeglądarki chcą to robić proaktywnie zużywają więc mniej energii i pamięci. Interfejs Page Lifecycle API udostępnia punkty zaczepienia cyklu życia, dzięki którym strony mogą bezpiecznie obsługiwać i interwencji bez wpływu na wygodę użytkowników. 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ą i zasobami Google Cloud. Na Androidzie, iOS i w najnowszych wersjach systemu Windows można uruchamiać aplikacje zatrzymana przez system operacyjny. Dzięki temu platformy mogą uprościć i usprawnić przydzielać zasoby tam, gdzie są najbardziej przydatne dla użytkownika.

W internecie wcześniej nie było takiego cyklu życia, a aplikacje można przechowywać, żyje bez końca. Przy dużej liczbie uruchomionych stron internetowych krytyczny system Zasoby takie jak pamięć, procesor, bateria i sieć mogą mieć nadmiarowe subskrypcje, co pogarsza wrażenia użytkowników.

Na platformie internetowej od dawna występowały zdarzenia związane ze stanami cyklu życia – np. load, unload i visibilitychange – te zdarzenia są dostępne tylko dla deweloperów aby reagować na zainicjowane przez użytkownika zmiany stanu cyklu życia. Aby internet mógł działać niezawodnie korzystające z urządzeń o niskim zużyciu energii (i przy większej świadomości zasobów na wszystkich platformach), potrzebują sposobu na proaktywne odzyskiwanie i przydzielanie systemu i zasobami Google Cloud.

Obecnie przeglądarki podejmują już aktywne działania, aby oszczędzać zasoby może wyświetlać się na kartach w tle, a wiele przeglądarek (zwłaszcza Chrome) robić to znacznie więcej, aby zmniejszyć ogólny zużycie zasobów.

Niestety deweloperzy nie są w stanie przygotować się na tego typu i interwencji inicjowanych przez system, a nawet wiedzą, że mają miejsce. Oznacza to, że że przeglądarki muszą być zachowawcze lub ryzykować uszkodzenia stron.

Interfejs Page Lifecycle API próbuje rozwiązać ten problem przez:

  • Wprowadzenie i ustandaryzowanie koncepcji stanów cyklu życia w internecie.
  • Definiowanie nowych stanów inicjowanych przez system, które umożliwiają przeglądarkom ograniczenie i które mogą zużywać ukryte lub nieaktywne karty.
  • Tworzenie nowych interfejsów API i zdarzeń, które umożliwiają programistom tworzenie stron internetowych przejścia do i z tych nowych stanów zainicjowanych przez system.

Zapewnia ono przewidywalność, której programiści stron internetowych potrzebują aplikacji, są odporne na interwencje systemowe i pozwalają przeglądarkom agresywnie optymalizują zasoby systemowe, co przynosi korzyści wszystkim użytkownikom internetu.

W pozostałej części tego posta omówimy nowe funkcje Cykl życia strony. i dowiedzieć się, jak mają się one do wszystkich stanów platformy internetowej. i zdarzeniach. Znajdziesz w nim też rekomendacje i sprawdzone metody pracy programistów, którzy powinni (i nie powinni) wykonywać w każdym stanie.

Omówienie stanów cyklu życia strony i zdarzeń

Wszystkie stany cyklu życia strony są dyskretne i wzajemnie się wykluczają, czyli strona może znajdować się tylko w jednym stanie naraz. większość zmian stanu cyklu życia strony, można zazwyczaj obserwować za pomocą zdarzeń DOM (wyjątki znajdziesz w zaleceniach dewelopera dla każdego stanu).

Prawdopodobnie najprostszy sposób na wyjaśnienie stanów cyklu życia strony, a także zdarzenia sygnalizujące przejście między nimi – to schemat:

Wizualna reprezentacja stanu i przebiegu zdarzeń opisanych w tym dokumencie.
Stan interfejsu Page Lifecycle API i przepływ zdarzeń.

Stany

Tabela poniżej zawiera szczegółowe informacje na temat każdego stanu. Wyświetlane są też możliwe stanów, które mogą wystąpić przed i po niej, jak również wydarzenia, które programiści mogą które pozwalają obserwować zmiany.

Stan Opis
Aktywne

Strona jest w stanie aktywna, jeśli jest widoczna i zawiera fokus wprowadzania.

Możliwe poprzednie stany:
pasywny (przez wydarzenie focus)
zawieszono (za pomocą zdarzenia resume, ciąg pageshow).

Możliwe kolejne stany:
pasywny (przez wydarzenie blur)

Pasywny

strona jest w stanie pasywnym, jeśli jest widoczna; nie są zaznaczone dane wejściowe.

Możliwe poprzednie stany:
aktywny (przez wydarzenie blur)
ukryte (przez visibilitychange)
zawieszono (za pomocą zdarzenia resume, następnie pageshow).

Możliwe kolejne stany:
aktywny (przez wydarzenie focus)
ukryte (przez visibilitychange)

Ukryta,

Strona jest ukryta, jeśli nie jest widoczna (oraz zostały zablokowane, odrzucone lub zamknięte).

Możliwe poprzednie stany:
pasywny (przez visibilitychange)
zawieszono (za pomocą zdarzenia resume, ciąg pageshow).

Możliwe kolejne stany:
pasywny (przez visibilitychange)
zawieszono (przez zdarzenie freeze)
odrzucone (brak uruchomionych zdarzeń)
zamknięto (brak uruchomionych zdarzeń)

Zamrożone

W stanie zawieszenia przeglądarka wstrzymuje wykonywanie można zablokować w sekcji w kolejkach zadań do momentu odblokowania strony. Oznacza to, że: Liczniki czasu JavaScript i wywołania zwrotne pobierania nie działają. Już uruchomiona które można ukończyć (przede wszystkim freeze), ale ich zakres może być ograniczony co potrafią i jak długo mogą wybiegać.

Przeglądarki blokują strony, aby ograniczyć wykorzystanie procesora, baterii i danych. oni To także sposób na szybsze nawigacji wstecz i do przodu – bez konieczności wyświetlania całej strony; załaduj ponownie.

Możliwe poprzednie stany:
ukryte (przez wydarzenie freeze)

Możliwe kolejne stany:
aktywny (za pomocą zdarzenia resume, a następnie pageshow)
pasywny (za pomocą zdarzenia resume, pageshow).
ukryte (przez zdarzenie resume)
odrzucone (nie uruchomiono żadnych zdarzeń)

Zakończona

Strona jest w stanie zakończenia po rozpoczęciu został usunięty z pamięci i usunięty z pamięci przez przeglądarkę. Nie w tym stanie mogą rozpoczynać się nowe zadania, a zadania w toku mogą być jeśli będą zbyt długo czekać.

Możliwe poprzednie stany:
ukryte (przez wydarzenie pagehide)

Możliwe kolejne stany:
BRAK

Odrzucono

Strona jest odrzucona, gdy zostaje wyładowana z pamięci w przeglądarce, aby oszczędzać zasoby. brak zadań, wywołań zwrotnych zdarzeń lub W tym stanie może być uruchamiany dowolny rodzaj kodu JavaScript, ponieważ zazwyczaj jest on odrzucany występują w przypadku ograniczeń zasobów, gdzie uruchamianie nowych procesów jest niemożliwe.

W stanie odrzucono samą kartę. (w tym tytuł karty i favikona) są zwykle widoczne dla użytkowników. mimo że strona zniknęła.

Możliwe poprzednie stany:
ukryte (nie uruchomiono żadnych zdarzeń)
zawieszone (nie uruchomiono żadnych zdarzeń)

Możliwe kolejne stany:
BRAK

Wydarzenia

Przeglądarki wysyłają wiele zdarzeń, ale tylko niewielka ich część sygnalizuje możliwa zmiana stanu cyklu życia strony. W poniższej tabeli znajdziesz informacje o wszystkich zdarzeniach które są powiązane z cyklem życia, i zawierają listę stanów, do których mogą przejść.

Nazwa Szczegóły
focus

Element DOM został zaznaczony.

Uwaga: zdarzenie focus nie muszą sygnalizować zmianę stanu. Sygnalizuje zmianę stanu tylko wtedy, gdy strona wcześniej nie była zaznaczony.

Możliwe poprzednie stany:
pasywny

Możliwe aktualne stany:
aktywny

blur

Element DOM stracił fokus.

Uwaga: zdarzenie blur nie muszą sygnalizować zmianę stanu. Sygnalizuje zmianę stanu tylko wtedy, gdy strona nie jest już aktywna (np. strona nie przełączyła się zaznaczenie z jednego elementu na drugi).

Możliwe poprzednie stany:
aktywny

Możliwe aktualne stany:
pasywny

visibilitychange

Identyfikator dokumentu Wartość visibilityState uległa zmianie. Może to spowodować Ma miejsce, gdy użytkownik przechodzi na nową stronę, przełącza karty, zamyka kartę lub minimalizuje lub zamyka przeglądarkę albo przełącza aplikacje podczas działania urządzenia mobilnego. systemów uczących się.

Możliwe poprzednie stany:
pasywny
ukryty

Możliwe aktualne stany:
pasywny
ukryty

freeze *

Strona została właśnie zablokowana. Dowolne zadania, które można zablokować, w kolejkach zadań na stronie nie zostaną uruchomione.

Możliwe poprzednie stany:
ukryte

Możliwe aktualne stany:
zamrożone

resume *

Przeglądarka wznowiła zablokowaną stronę.

Możliwe poprzednie stany:
zamrożone

Możliwe aktualne stany:
aktywny (jeśli po nim następuje znak pageshow)
pasywne (jeśli po nim następuje znak . pageshow)
ukryte

pageshow

Trwa przeglądanie wpisu historii sesji.

Może to być wczytanie zupełnie nowej strony lub wyświetlenie strony pobranej z pamięci podręcznej stanu strony internetowej. Jeśli strona zostało pobrane z pamięci podręcznej stanu strony internetowej, Właściwość persisted ma wartość true, w przeciwnym razie jest false

Możliwe poprzednie stany:
zamrożone (resume zdarzenie)

Możliwe aktualne stany:
aktywny
pasywny
ukryte

pagehide

Przechodzimy przez wpis historii sesji.

Jeśli użytkownik przechodzi na inną stronę, a przeglądarka może dodać przejście z bieżącej strony na wstecz/dalej Cache do ponownego wykorzystania w późniejszym czasie, właściwość persisted zdarzenia jest true. Gdy true, strona przechodzi do sekcji stan zablokowany; w przeciwnym razie przechodzi w stan zakończony.

Możliwe poprzednie stany:
ukryte

Możliwe aktualne stany:
zamrożone (event.persisted to prawda, freeze obserwowane wydarzenie)
zamknięto (event.persisted to fałsz, unload występuje zdarzenie)

beforeunload

Okno, dokument i jego zasoby zostaną wkrótce wyładowane. Dokument jest nadal widoczny i można anulować to wydarzenie .

Ważne: wydarzenie beforeunload powinny być używane jedynie do powiadamiania użytkownika o niezapisanych zmianach. Gdy już zapisane zmiany, wydarzenie należy usunąć. Nigdy nie bezwarunkowo dodawane do strony, co może negatywnie wpłynąć na wydajność w niektórych przypadkach. Zobacz starszą wersję API.

Możliwe poprzednie stany:
ukryte

Możliwe aktualne stany:
zakończone

unload

Trwa wyładowywanie strony.

Ostrzeżenie: używanie zdarzenia unload nigdy nie jest zalecane, ponieważ jest zawodny i w niektórych przypadkach może negatywnie wpłynąć na wydajność. Zobacz sekcja dotycząca starszych interfejsów API , aby dowiedzieć się więcej.

Możliwe poprzednie stany:
ukryte

Możliwe aktualne stany:
zakończone

* 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 inicjowane przez użytkownika: zablokowane i odrzucone; Jak już wspominaliśmy, obecne przeglądarki już czasem zawieszają się i usuwają na ukrytych kartach (według własnego uznania), ale deweloperzy nie mają żadnego sposobu na to, to właśnie się dzieje.

W Chrome 68 deweloperzy mogą teraz obserwować, kiedy ukryta karta jest wstrzymywana odblokowujesz, słuchając utworu freeze i wydarzenia resume w dniu document.

document.addEventListener('freeze', (event) => {
  // The page is now frozen.
});

document.addEventListener('resume', (event) => {
  // The page has been unfrozen.
});

Od Chrome w wersji 68 obiekt document zawiera teraz wasDiscarded. w przeglądarce Chrome na komputerze (w tym problemie monitorujemy pomoc dotyczącą Androida). Sprawdzanie, czy strona została odrzucona po ukryciu , możesz sprawdzić jej wartość w czasie wczytywania strony (uwaga: aby ponownie użyć odrzuconych stron, trzeba je ponownie załadować).

if (document.wasDiscarded) {
  // Page was previously discarded by the browser while in a hidden tab.
}

Porady na temat tego, co należy zrobić na stronie freeze i resume oraz jak postępować w przypadku odrzucania stron i jak przygotować się na nie, zapoznaj się z artykułem zalecenia dla deweloperów dotyczące każdego stanu.

W kilku kolejnych sekcjach znajdziesz omówienie tego, jak nowe funkcje istniejących stanów i zdarzeń platformy internetowej.

Jak obserwować stany cyklu życia strony w kodzie

Dostępne opcje: aktywne, pasywne i ukryte można uruchomić kod JavaScript, który określi bieżącą Stan cyklu życia strony z istniejących interfejsów API platformy internetowej.

const getState = () => {
  if (document.visibilityState === 'hidden') {
    return 'hidden';
  }
  if (document.hasFocus()) {
    return 'active';
  }
  return 'passive';
};

Stany zawieszone i zakończone na może zostać wykryty tylko w odpowiednich detektorach zdarzeń. (freeze i pagehide) zgodnie z stanem zmian.

Jak obserwować zmiany stanu

Korzystając z zdefiniowanej wcześniej funkcji getState(), możesz obserwować wszystkie strony Stan cyklu życia zmieni się za pomocą tego 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 akceptuje następny stan, a jeśli wystąpiła zmiana, rejestruje zmiany stanu w konsoli.
  • Dodania rejestrowanie detektorów wszystkich niezbędnych zdarzeń cyklu życia, które z kolei wywołują logStateChange() z następnym stanem.

Warto zapamiętać, że wszystkie detektory zdarzeń zostały dodane do: window. Wszystkie te osoby {capture: true} Dzieje się tak z kilku przyczyn:

  • Nie wszystkie zdarzenia cyklu życia strony mają tę samą wartość docelową. pagehide i pageshow są uruchamiane na window; visibilitychange, freeze i Roboty resume są uruchamiane w dniu document, a w przypadku ich kont tagi „focus” i „blur” są uruchamiane odpowiednich elementów DOM.
  • Większość z tych zdarzeń nie jest wyświetlana jako bąbelki, co oznacza, że nie da się dodać nieprzechwytujących detektorów zdarzeń ze wspólnym elementem nadrzędnym i obserwować wszystkie z nich.
  • faza przechwytywania następuje przed fazą celu lub bąbelka, więc dodanie pozwalają na ich uruchomienie, zanim inny kod je anuluje.

Rekomendacje deweloperów w każdym stanie

Ponieważ jesteś deweloperem, ważne jest, aby rozumieć stany cyklu życia strony oraz jak obserwować je w kodzie – trzeba wiedzieć, jaki rodzaj pracy należy (i powinno) zależy od stanu strony.

Na przykład wyświetlanie powiadomienia tymczasowego nie ma sensu w przypadku, gdy strona jest ukryta. Ten przykład jest całkiem niezły są też inne, niezbyt oczywiste rekomendacje, które nie są tak oczywiste. wyliczać.

Stan Rekomendacje dla deweloperów
Active

Stan aktywny to czas o największym znaczeniu dla użytkownika, to najważniejszy moment w odpowiedzi na dane wejściowe użytkownika.

Obniż priorytet wszelkich prac niezwiązanych z interfejsem, które mogą blokować wątek główny do okresy bezczynności lub do instancji roboczej.

Passive

w stanie pasywnym: użytkownik nie wchodzi w interakcję ze stroną; ale i tak go widzą. Oznacza to, że aktualizacje interfejsu i animacje powinny jednak te zmiany nie mają znaczenia.

Zmiana z aktywnej na pasywną po zmianie stanu strony to dobry czas na zachowanie niezapisanego stanu aplikacji.

Hidden

Zmiana z pasywnej na ukrytą po zmianie strony użytkownik nie będzie mógł już z niej korzystać, dopóki plik nie zostanie ponownie załadowany.

Przejście do stanu ukryte jest też często ostatnią zmianą stanu. która jest wiarygodna i widoczna dla programistów (zwłaszcza w przypadku aplikacji gdy użytkownicy mogą zamykać karty lub samą przeglądarkę. beforeunload, pagehide i unload w takich przypadkach nie są wywoływane).

Oznacza to, że stan ukryty należy traktować jako prawdopodobny koniec tagu w ramach sesji użytkownika. Inaczej mówiąc, zachowuj niezapisany stan aplikacji i wysyłać niewysłane dane analityczne.

Należy także przestać wprowadzać aktualizacje interfejsu (ponieważ nie będą one widoczne przez użytkownika), a także należy zatrzymać wszystkie działania, które użytkownik nie chciałby który działa w tle.

Frozen

W stanie zawieszenia które można zablokować Kolejki zadań będą zawieszone do czasu odblokowania strony, co może nigdy nie nastąpić (np. jeśli strona zostanie odrzucona).

Oznacza to, że strona zmienia się z ukryta na zablokowana. ważne jest zatrzymanie liczników czasu lub zerwanie połączeń, jeśli jest zablokowany, może mieć wpływ na inne otwarte karty w tym samym pochodzeniu lub umieszczenie strony w pamięci podręcznej stanu strony internetowej.

Szczególnie ważne jest, aby:

Należy też zachować każdy stan widoku dynamicznego (np. pozycję przewijania) w widoku nieskończonej listy), sessionStorage (lub IndexedDB przez commit()), które chcesz przywrócić, jeśli strona została została odrzucona i załadowana ponownie później.

Jeśli strona zmienia się z zablokowanej z powrotem na ukrytą, możesz ponownie otworzyć wszystkie zamknięte połączenia lub ponownie uruchomić sondowanie zatrzymana, gdy strona była po raz pierwszy zablokowana.

Terminated

Zazwyczaj nie musisz podejmować żadnych działań podczas przechodzenia między stronami w stan zakończony.

Ponieważ strony wyładowane z pamięci w wyniku działania użytkownika zawsze przejdź przez stan ukryty przed wejściem w parametr zakończony. stan ukryty oznacza, że logika zakończenia sesji (np. zachowywanie stanu aplikacji i raportowanie jej do analityki) przeprowadzonych przez nas działań.

Ponadto (jak wspomniano w zaleceniach dla ukryty), ważne jest, aby deweloperzy zdali sobie sprawę, że przejście do stanu zakończonego nie może być prawidłowo wykrywane w wielu przypadkach (zwłaszcza na urządzeniach mobilnych), więc deweloperzy, którzy po zakończeniu zdarzenia (np. beforeunload, pagehide i unload) prawdopodobnie utracą dane.

Discarded

Stan odrzucony nie jest widoczny dla programistów w za każdym razem, gdy strona jest odrzucana. Dzieje się tak, ponieważ strony są zwykle odrzucone z powodu ograniczeń zasobów oraz odblokowywanie strony tylko w celu w odpowiedzi na zdarzenie odrzucenia jest po prostu niemożliwe w w większości przypadków.

W związku z tym należy przygotować się na możliwość odrzucenia zmień stan z ukryty na zablokowany. na przywrócenie odrzuconej strony podczas jej wczytywania przez sprawdzam document.wasDiscarded.

Przypominamy, że niezawodność i kolejność zdarzeń cyklu życia nie są spójnie wdrożona we wszystkich przeglądarkach, w tabeli jest użycie PageLifecycle.js.

Unikaj starszych interfejsów API cyklu życia

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 końca sesji, żeby zapisać stan i wysłać dane analityczne. jest bardzo mało wiarygodne, zwłaszcza na urządzeniach mobilnych. Zdarzenie unload nie: uruchamianie w wielu typowych sytuacjach, w tym podczas zamykania karty z karty. na urządzeniu mobilnym lub zamknij aplikację w przeglądarce.

Z tego powodu lepiej zawsze polegać na visibilitychange, aby określić, kiedy i uważamy, że stan ukryty jest ostatni niezawodny czas na oszczędzanie danych aplikacji i użytkowników.

Ponadto samo obecność zarejestrowanego modułu obsługi zdarzeń unload (w ramach onunload lub addEventListener()) może uniemożliwiać przeglądarkom aby szybciej umieszczać strony w pamięci podręcznej stanu strony internetowej wczytywania stron w przód i w tył.

We wszystkich nowoczesnych przeglądarkach zaleca się używanie pagehide, aby wykryć możliwe usunięcia strony (czyli zakończone), a nie w przypadku zdarzenia unload. Jeśli przeglądarki Internet Explorer w wersji 10 lub starszej, dodaj wykrywają zdarzenie pagehide i używają unload tylko wtedy, gdy przeglądarka nie obsługuje tej funkcji 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

ze zdarzeniem beforeunload występuje podobny problem jak ze zdarzeniem unload, ponieważ: wcześniej wystąpienie zdarzenia beforeunload uniemożliwiało stronom kwalifikuje się do korzystania z pamięci podręcznej stanu strony internetowej. Nowoczesne przeglądarki nie mają tego ograniczenia. Chociaż niektóre przeglądarki nie uruchamiają się ze względów bezpieczeństwa zdarzenie beforeunload podczas próby umieszczenia strony w przebiegu stanu strony internetowej. pamięci podręcznej, co oznacza, że zdarzenie nie jest wiarygodne jako sygnał zakończenia sesji. Oprócz tego niektóre przeglądarki (w tym Chrome) wymagać interakcji użytkownika na stronie przed zezwoleniem na zdarzenie beforeunload uruchomienia, co jeszcze bardziej wpływa na jego niezawodność.

Jedna z różnic między beforeunload a unload jest taka, że występuje zgodnie z prawem (beforeunload). Gdy na przykład chcesz ostrzec użytkownika, o niezapisanych zmianach, które utracą, jeśli będą kontynuować usuwanie strony.

Istnieją pewne powody, dla których warto używać usługi beforeunload, dlatego zalecamy tylko dodaj odbiorniki beforeunload, gdy użytkownik ma niezapisane zmiany, a następnie usuwać je natychmiast po ich zapisaniu.

Nie rób tego, ponieważ spowoduje to dodanie detektora beforeunload bezwarunkowo):

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);
  }
});

Zrób tak (bo dodaje detektor beforeunload tylko wtedy, gdy i usuwa ją, gdy nie jest potrzebna):

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 widzę przycisku „wczytywania”? w jakimś stanie?

Interfejs Page Lifecycle API określa stany, które są dyskretne i wzajemnie się wykluczają. Ponieważ strona może być ładowana jako aktywna, pasywna lub ukryta, ponieważ może on zmienić stan – a nawet zostać zamknięty – przed zakończeniem wczytywania, w tym modelu nie ma sensu.

Moja strona działa, gdy jest ukryta. Jak mogę zapobiec jej zablokowaniu lub odrzuceniu?

Istnieje wiele uzasadnionych powodów, dla których strony internetowe nie powinny być blokowane w stanie ukrytym. Najbardziej oczywistym przykładem jest aplikacja do odtwarzania muzyki.

Są też sytuacje, gdy odrzucenie strony przez Chrome może być ryzykowne, np. jeśli zawiera formularz z nieprzesłanymi danymi wejściowymi użytkownika Moduł obsługi beforeunload, który ostrzega przed wyładowywaniem strony.

Na razie Chrome będzie ostrożnie odrzucać strony i rób to tylko wtedy, gdy masz pewność, że nie ma to wpływu na użytkowników. Na przykład strony, które gdy zaobserwowano, że w trybie ukrycia wykonywana jest któraś z poniższych czynności. zostać odrzucona, chyba że zasoby są bardzo ograniczone:

  • Odtwarzam dźwięk
  • Korzystanie z WebRTC
  • Aktualizowanie tytułu lub favikony tabeli
  • Pokazuję alerty
  • Wysyłam powiadomienia push

Na potrzeby bieżącej listy funkcji służących do określania, czy karta może być bezpiecznie zamrożone lub odrzucone, patrz: Heurystyka do zamrażania & Odrzucam w Chrome.

Co to jest pamięć podręczna stanu strony internetowej?

Pamięć podręczna stanu strony internetowej to termin opisujący optymalizacja nawigacji w niektórych przeglądarkach, czyli korzystanie z przyciskach przejścia dalej.

Gdy użytkownik opuści stronę, przeglądarki blokują jej wersję aby można ją było szybko wznowić w razie powrotu użytkownika za pomocą za pomocą przycisków Wstecz i Dalej. Pamiętaj, że dodanie właściwości unload moduł obsługi zdarzeń uniemożliwia przeprowadzenie tej optymalizacji.

We wszystkich intencjach i celach to zawieszenie działa tak samo jak które zawieszają się, by oszczędzać procesor lub baterię; Dlatego jest to jest częścią zawieszonego stanu cyklu życia.

Jak mogę zapisać dane w IndexedDB, jeśli nie mogę uruchomić asynchronicznych interfejsów API w stanie zawieszenia lub zakończenia?

W stanach zablokowanych i zablokowanych zadania, które można zablokować w kolejkach zadań na stronie. są zawieszone, co oznacza, że interfejsy API asynchroniczne i oparte na wywołaniach zwrotnych, takie jak IndexedDB których nie da się prawidłowo użyć.

W przyszłości dodamy do obiektów IDBTransaction metodę commit(), która pozwoli Zapewnij programistom możliwość przeprowadzania transakcji w rzeczywistości w trybie tylko do zapisu które nie wymagają wywołań zwrotnych. Innymi słowy, jeśli deweloper tylko pisze, danych do IndexedDB bez wykonywania złożonej transakcji składającej się z odczytów i zapisy, metoda commit() będzie mogła zakończyć działanie, zanim kolejki zadań zostaną zawieszone (przy założeniu, że baza danych IndexedDB jest już otwarta).

W przypadku kodu, który musi już działać dzisiaj, programiści mają do wyboru 2 opcje:

  • Użycie pamięci sesji: miejsce na dane sesji jest synchroniczny i zachowywany w ramach odrzucania stron.
  • Użyj metody IndexedDB z skryptu service worker: skrypt service worker może przechowywać dane IndexedDB po zamknięciu lub odrzuceniu strony. W: freeze lub Detektor zdarzeń pagehide, przez który możesz wysyłać dane do skryptu service worker postMessage(), a skrypt service worker może zapisać dane.
.

Testowanie aplikacji w stanie blokady i odrzuconej

Aby sprawdzić, jak aplikacja działa w stanie blokady i odrzucenia, otwórz stronę chrome://discards, aby zablokować lub odrzucić otwartych kart.

Chrome odrzuca interfejs użytkownika
Chrome odrzuca interfejs użytkownika

Dzięki temu będziesz mieć pewność, że strona prawidłowo obsługuje atrybuty freeze i resume zdarzeń oraz flagę document.wasDiscarded, gdy strony są odświeżane po odrzucenie.

Podsumowanie

Deweloperzy, którzy chcą szanować zasoby systemowe urządzeń użytkowników przy tworzeniu aplikacji z myślą o stanach cyklu życia strony. Bardzo ważne jest, nie zużywają nadmiernych zasobów systemowych w sytuacjach, w których użytkownik nie spodziewałby się

Im więcej deweloperów zacznie wdrażać nowe interfejsy API cyklu życia strony, tym bezpieczniejsze umożliwia przeglądarkom blokowanie i odrzucanie nieużywanych stron. Ten przeglądarki zużywają mniej pamięci, procesora, baterii i zasobów sieciowych co jest korzystne dla użytkowników.