Rejestracja skryptu service worker

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 komfortu 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.

Jeśli zdarzyło Ci się czytać o mechanizmach Service Worker, na pewno natrafisz na schemat bardzo podobny 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 jest to zaskoczeniem (biorąc pod uwagę, że ten artykuł się na tym nie kończy), więc odpowiedź na oba pytania brzmi „tak”.

Pierwsza wizyta użytkownika

Rozważmy sytuację, gdy użytkownik po raz pierwszy otwiera aplikację internetową. W tym momencie nie ma jeszcze serwisowego workera, a przeglądarka nie ma możliwości, aby z wyprzedzeniem wiedzieć, czy w ostateczności zostanie zainstalowany.

Jako programista Twoim priorytetem powinno być dopilnowanie, by przeglądarka szybko pobierała minimalny zestaw niezbędnych zasobów do wyświetlenia interaktywnej strony. Wszystko, co spowalnia uzyskanie odpowiedzi, to wroga rozgrywka, która szybko staje się interaktywna.

Teraz wyobraź sobie, że w trakcie pobierania JavaScriptu lub obrazów, które musi wyrenderować strona, przeglądarka decyduje się rozpocząć wątek lub proces w tle (aby zachować zwięzłość, zakładamy, że 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. Rozkręcenie tego dodatkowego wątku zwiększa rywalizację o czas procesora i pamięć, które przeglądarka mogłaby wydać na wyrenderowanie interaktywnej strony internetowej.

Bezczynny wątek w tle prawdopodobnie nie zmieni zasadniczej różnicy. 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 wysunąć się obawy dotyczące ograniczonej przepustowości dostępnej dla wielu urządzeń mobilnych. Przepustowość jest bardzo ważna, dlatego nie ograniczaj krytycznych zasobów, pobierając zasoby dodatkowe w tym samym czasie.

Oznacza to, że uruchomienie nowego wątku service workera 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 service workera 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');
    });
}

Odpowiednia chwila na rozpoczęcie rejestracji usługi może też zależeć od tego, co robi Twoja aplikacja internetowa tuż 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ół stwierdził, że rozpoczęcie rejestracji skryptu service worker w trakcie animacji może powodować nieporozumienia na mniej zaawansowanych urządzeniach mobilnych. Zamiast tworzyć użytkownikom problemy, opóźniliśmy rejestrację service workera do momentu po animacji, gdy przeglądarka najprawdopodobniej miała kilka sekund bezczynności.

Podobnie, 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 workera? Dla niektórych użytkowników może się to dziwić, ale nie powinno to mieć żadnego wpływu.

Gdy skrypt service worker zostanie zarejestrowany, przechodzi przez installactivate zdarzenia cyklu życia. Po aktywacji skrypt service worker może obsługiwać zdarzenia fetch w przypadku wszystkich kolejnych wizyt w Twojej aplikacji internetowej. Skrypt service worker 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 service worker, navigator.serviceWorker.register() podczas kolejnych wizyt będzie w rzeczywistości 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ć usługę? Jednym z takich przypadków jest sytuacja, gdy skrypt service worker używa clients.claim() do przejęcia kontroli nad stroną podczas pierwszej wizyty, a także agresywnie 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 wykonywania 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 ramach usługi workera nie prosi o zasoby, które konkurują o przepustowość z prośbami 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. Jeśli jednak ponownie odwiedzisz witrynę, gdy będzie już mechanizm Service Worker i w pełni zapełnione pamięci podręczne, nie odniesiesz takich samych wrażeń jak nowy użytkownik. Łatwo jest też zignorować 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.

Ruch w sieci z wcześniejszą rejestracją.

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 (wpisy z ikoną koła zębatego obok nich pochodzące z modułu obsługi install skryptu) przeplatają się z żądaniami innych zasobów niezbędnych do wyświetlenia strony.

Ruch sieciowy z opóźnionym rejestrowaniem.

Na zrzucie ekranu powyżej rejestracja skryptu service worker została opóźniona do momentu załadowania strony. Jak widać, żądania wstępnego buforowania nie są wysyłane, dopóki wszystkie zasoby nie zostaną pobrane z sieci, co eliminuje wszelkie konflikty 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 zapewnić, możesz opóźnić rejestrację pracownika obsługi klienta do momentu załadowania strony podczas pierwszej wizyty. Nadal masz dostęp do wszystkich korzyści płynących z usług Service Worker przy kolejnych wizytach.

Prostym sposobem na opóźnienie początkowej rejestracji skryptu service worker do czasu załadowania pierwszej strony jest użycie tego:

if ('serviceWorker' in navigator) {
    window.addEventListener('load', function() {
    navigator.serviceWorker.register('/service-worker.js');
    });
}