Ograniczanie opóźnień w nawigacji
Często zdarza się, że w momencie zamknięcia strony lub aplikacji przez użytkownika znajdują się na niej nieprzesłane dane analityczne lub inne dane. Aby zapobiec utracie danych, niektóre witryny używają wywołania synchronicznego XMLHttpRequest()
, aby utrzymać stronę lub aplikację otwartą do czasu przekazania danych na serwer. Istnieją lepsze sposoby zapisywania danych, a ta technika powoduje opóźnienie zamykania strony nawet o kilka sekund, co powoduje nieprzyjemne wrażenia użytkownika.
To podejście musi się zmienić, a przeglądarki reagują na nie. Specyfikacja XMLHttpRequest()
jest przeznaczona do wycofania i usunięcia. W pierwszej kolejności Chrome 80 blokuje wywołania synchroniczne w kilku modułach obsługi zdarzeń, w szczególności beforeunload
, unload
, pagehide
i visibilitychange
, gdy są one uruchamiane w ramach odrzucenia. Niedawno zespół WebKit wprowadził tę samą zmianę działania.
W tym artykule opiszę krótko opcje dla osób, które potrzebują czasu na zaktualizowanie swoich witryn, oraz przedstawię alternatywne rozwiązania dla XMLHttpRequest()
.
Tymczasowe rezygnacje
Chrome nie chce po prostu odłączyć XMLHttpRequest()
, dlatego dostępne są tymczasowe opcje rezygnacji. W przypadku witryn w internecie dostępny jest okres próbny.
W ten sposób do nagłówków stron dodasz token dotyczący pochodzenia, który umożliwia asynchroniczne wywołania XMLHttpRequest()
. Ta opcja zostanie wycofana w marcu 2021 r., tuż przed wydaniem Chrome 89. Klienci korzystający z Chrome Enterprise mogą też użyć flagi zasad AllowSyncXHRInPageDismissal
, która wygasa w tym samym czasie.
Alternatywy
Niezależnie od tego, jak wysyłasz dane z powrotem na serwer, nie warto czekać, aż strona się rozładuje, aby wysłać wszystkie dane naraz. Oprócz tego, że powoduje nieprzyjemne wrażenia użytkownika, unload jest niepewnym rozwiązaniem w przypadku nowoczesnych przeglądarek i może spowodować utratę danych, jeśli coś pójdzie nie tak. W szczególności zdarzenia unload często nie są wywoływane w przeglądarkach mobilnych, ponieważ w systemach operacyjnych urządzeń mobilnych istnieje wiele sposobów na zamknięcie karty lub przeglądarki bez wywołania zdarzenia unload
.
W przypadku XMLHttpRequest()
używanie małych ładunków było opcjonalne. Teraz jest to wymagane. Zgodnie ze specyfikacją obie jego wersje mogą mieć limit przesyłania wynoszący 64 KB na kontekst.
Pobieranie informacji o utrzymywaniu aktywności
Interfejs Fetch API zapewnia niezawodne narzędzie do obsługi interakcji z serwerem oraz spójny interfejs do stosowania w różnych interfejsach API platform. Wśród dostępnych opcji jest keepalive
, który zapewnia ciągłość żądania niezależnie od tego, czy strona, na której zostało ono wyświetlone, pozostaje otwarta:
window.addEventListener('unload', {
fetch('/siteAnalytics', {
method: 'POST',
body: getStatistics(),
keepalive: true
});
}
Metoda fetch()
ma tę zaletę, że zapewnia większą kontrolę nad tym, co jest wysyłane do serwera. W przykładzie nie pokazuję, że funkcja fetch()
zwraca również obietnicę, która rozwiązuje się z obiektem Response
. Próbuję pozbyć się sposobu wczytywania strony, więc nie robię z tym nic.
SendBeacon()
SendBeacon()
w podstawie korzysta z interfejsu Fetch API, dlatego ma to samo ograniczenie ładunku 64 KB i zapewnia, że żądanie jest kontynuowane po usunięciu strony. Jego główną zaletą jest prostota. Umożliwia on przesyłanie danych za pomocą pojedynczego wiersza kodu:
window.addEventListener('unload', {
navigator.sendBeacon('/siteAnalytics', getStatistics());
}
Podsumowanie
Dzięki zwiększonej dostępności
fetch()
w różnych przeglądarkach XMLHttpRequest()
zostanie w pewnym momencie prawdopodobnie usunięta z platformy internetowej. Dostawcy przeglądarek zgadzają się, że należy je usunąć, ale zajmie to trochę czasu. Wycofanie jednej z najgorszych opcji użycia to pierwszy krok, który poprawia wrażenia użytkowników.
Zdjęcie: Matthew Hamilton, Unsplash