Sprawdzone metody określania czasu rejestracji usługi.
Pracownicy usług mogą znacznie przyspieszyć powtarzane wizyty w aplikacji internetowej, ale musisz zadbać o to, aby początkowa instalacja takiego pracownika nie pogorszyła wrażeń użytkownika podczas pierwszej wizyty.
Ogólnie odroczenie rejestracji workera usługi do momentu załadowania początkowej strony zapewni użytkownikom najlepszą jakość, zwłaszcza na urządzeniach mobilnych z wolniejszymi połączeniami z internetem.
Typowy tekst schematyczny rejestracji
Jeśli kiedykolwiek czytałeś/czytałaś o usługach działających w tle, prawdopodobnie natknąłeś/natkniesz się na szablony podobne do tego:
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/service-worker.js');
}
Czasami może to być poprzedzone kilkoma instrukcjami console.log()
lub kodem, który wykrywa aktualizację poprzedniej rejestracji skryptu service worker. Ma to na celu poinformowanie użytkowników o konieczności odświeżenia strony. To jednak tylko drobne zmiany w standardowych kilku liniach kodu.
Czy navigator.serviceWorker.register
ma jakieś niuanse? Czy są jakieś sprawdzone metody, które warto stosować? Nie dziwi, że odpowiedź na oba pytania brzmi „tak” (ponieważ ten artykuł się na tym nie kończy).
Pierwsza wizyta użytkownika
Rozważmy sytuację, gdy użytkownik po raz pierwszy odwiedza aplikację internetową. W tym momencie nie ma jeszcze serwisowego workera, a przeglądarka nie ma możliwości, aby z wyprzedzeniem wiedzieć, czy w końcu zostanie zainstalowany.
Jako deweloper powinieneś przede wszystkim zadbać o to, aby przeglądarka szybko pobierała minimalny zestaw kluczowych zasobów potrzebnych do wyświetlenia interaktywnej strony. Wszystko, co spowalnia pobieranie tych odpowiedzi, jest wrogiem szybkiego czasu reakcji na interakcje.
Załóżmy, że w trakcie pobierania kodu JavaScript lub obrazów, które strona musi renderować, przeglądarka uruchamia wątek lub proces w tle (dla zwiękłości przyjmijmy, że jest to wątek). Załóżmy, że nie korzystasz z potężnego komputera stacjonarnego, ale z niezbyt wydajnego telefonu komórkowego, który dla wielu osób jest głównym urządzeniem. Uruchomienie tego dodatkowego wątku zwiększa konkurencję o czas procesora i pamięć, które w przeciwnym razie byłyby wykorzystywane przez przeglądarkę do renderowania interaktywnej strony internetowej.
Nieużywany wątek w tle raczej nie będzie miał większego znaczenia. Co jednak, jeśli ten wątek nie jest nieaktywny, ale zamiast tego decyduje się również pobrać zasoby z sieci? Wszelkie obawy dotyczące procesora lub pamięci powinny zejść na dalszy plan, a na pierwszy plan powinny wysunąć się obawy dotyczące ograniczonej przepustowości dostępnej dla wielu urządzeń mobilnych. Przepustowość jest cenna, więc nie pogarszaj sytuacji krytycznych zasobów, pobierając jednocześnie zasoby drugorzędne.
Oznacza to, że uruchomienie nowego wątku usługi w celu pobrania i zapisania do pamięci podręcznej zasobów w tle może utrudnić osiągnięcie celu, jakim jest zapewnienie jak najkrótszego czasu do interakcji podczas pierwszej wizyty użytkownika w witrynie.
Ulepszanie szablonu
Rozwiązaniem jest kontrolowanie rozpoczęcia działania pracownika usługi przez wybór momentu wywołanianavigator.serviceWorker.register()
. Prostą regułą jest opóźnienie rejestracji do momentu, gdy funkcja load
event
zostanie wywołana na window
, na przykład:
if ('serviceWorker' in navigator) {
window.addEventListener('load', function() {
navigator.serviceWorker.register('/service-worker.js');
});
}
Właściwy moment rejestracji pracownika usługi może jednak zależeć od tego, co robi Twoja aplikacja internetowa zaraz po załadowaniu. Na przykład aplikacja internetowa Google I/O 2016 zawiera krótką animację przed przejściem do ekranu głównego. Nasz zespół wykazał, że rozpoczęcie rejestracji service workera podczas animacji może spowodować niepłynność na słabszych urządzeniach mobilnych. Zamiast zmuszać użytkowników do korzystania z niewygodnej funkcji, opóźniliśmy rejestrację service workera do momentu po zakończeniu animacji, gdy przeglądarka najprawdopodobniej miała kilka sekund bezczynności.
Jeśli Twoja aplikacja internetowa korzysta z ramy, która wykonuje dodatkowe czynności konfiguracyjne po załadowaniu strony, poszukaj zdarzenia związanego z ramą, które sygnalizuje, że te czynności zostały wykonane.
Kolejne wizyty
Do tej pory skupialiśmy się na pierwszej wizycie, ale jaki wpływ na powtarzające się wizyty w Twojej witrynie ma opóźnione rejestrowanie usługi? Może to niektórych zaskoczyć, ale nie powinno to mieć żadnego wpływu.
Gdy skrypt service worker zostanie zarejestrowany, przechodzi przez install
i activate
zdarzenia cyklu życia.
Po aktywacji skrypt service worker może obsługiwać zdarzenia fetch
w przypadku wszystkich kolejnych wizyt w Twojej aplikacji internetowej. Uruchamia się przed wysłaniem żądania dotyczącego dowolnej strony w zakresie jego działania, co jest logiczne. Jeśli istniejący pracownik sieci nie działał już przed odwiedzeniem strony, nie będzie miał możliwości obsługi zdarzeń fetch
w przypadku żądań nawigacji.
Gdy aktywny pracownik obsługi klienta wykona zadanie, nie ma znaczenia, kiedy to zrobisz (navigator.serviceWorker.register()
) ani czy w ogóle to zrobisz.
Jeśli nie zmienisz adresu URL skryptu usługi, podczas kolejnych wizyt navigator.serviceWorker.register()
będzie miało wartość no-op. Czas wywołania nie ma znaczenia.
Powody, dla których warto zarejestrować się wcześniej
Czy są jakieś sytuacje, w których warto jak najszybciej zarejestrować pracownika usługi? Jednym z takich przypadków jest sytuacja, gdy skrypt service worker korzysta z clients.claim()
, aby przejąć kontrolę nad stroną podczas pierwszej wizyty, i intensywnie wykonuje buforowanie w czasie działania w obiekcie fetch
. W takim przypadku warto jak najszybciej aktywować usługę wtyczki, aby wypełnić pamięć podręczną w czasie działania zasobami, które mogą się przydać w przyszłości. Jeśli Twoja aplikacja internetowa należy do tej kategorii, warto się zastanowić, czy menedżer install
w workerze usług nie prosi o zasoby, które konkurują o przepustowość z żądaniami strony głównej.
Testowanie
Doskonałym sposobem na symulowanie pierwszej wizyty jest otwarcie aplikacji internetowej w oknie incognito w Chrome i sprawdzenie ruchu w sieci w narzędziach DevTools w Chrome. Jako programista witryn internetowych prawdopodobnie wczytujesz lokalny egzemplarz swojej aplikacji internetowej dziesiątki razy dziennie. Jednak gdy wracasz do witryny, gdy jest już tam worker i pełne pamięci podręczne, nie uzyskasz takich samych wrażeń, jakie ma nowy użytkownik, i łatwo zignorujesz potencjalny problem.
Oto przykład, który pokazuje, jak duży wpływ na rejestrację może mieć czas jej zgłoszenia. Oba zrzuty ekranu zostały zrobione podczas korzystania z próbnej aplikacji w trybie incognito z ograniczeniem przepustowości sieci, aby symulować wolne połączenie.

Zrzut ekranu powyżej pokazuje ruch sieciowy, gdy próbka została zmodyfikowana, aby jak najszybciej zarejestrować usługę workera. Możesz zobaczyć żądania wstępnego buforowania (elementy z ikoną koła zębatego obok, pochodzące z obsługi install
modułu service workera) przeplatane z żądaniami innych zasobów potrzebnych do wyświetlenia strony.

Na zrzucie ekranu powyżej rejestracja skryptu service worker została opóźniona do momentu załadowania strony. Widać, że żądania wstępnego buforowania nie są wysyłane, dopóki wszystkie zasoby nie zostaną pobrane z sieci, co eliminuje wszelkie spory dotyczące przepustowości. Co więcej, ponieważ niektóre z elementów, które pobieramy z wyprzedzeniem, są już w pamięci podręcznej HTTP przeglądarki (elementy z wartością (from disk cache)
w kolumnie „Rozmiar”), możemy wypełnić pamięć podręczną usługi bez konieczności ponownego korzystania z sieci.
Bonusowe punkty, jeśli przeprowadzisz tego typu test na prawdziwym urządzeniu niskobudżetowym w rzeczywistej sieci mobilnej. Możesz skorzystać z możliwości zdalnego debugowania Chrome, aby podłączyć telefon z Androidem do komputera za pomocą kabla USB i sprawdzić, czy przeprowadzane testy rzeczywiście odzwierciedlają rzeczywiste wrażenia wielu użytkowników.
Podsumowanie
Podsumowując, najwyższym priorytetem powinno być zapewnienie użytkownikom jak najlepszego wrażenia podczas pierwszej wizyty. Aby to osiągnąć, możesz opóźnić rejestrację skryptu service worker do momentu załadowania strony podczas pierwszej wizyty. Nadal będziesz mieć dostęp do wszystkich zalet korzystania z usług dla robota w przypadku powtarzających się wizyt.
Prosty sposób na opóźnienie początkowej rejestracji service workera do momentu załadowania pierwszej strony:
if ('serviceWorker' in navigator) {
window.addEventListener('load', function() {
navigator.serviceWorker.register('/service-worker.js');
});
}