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.

Schemat treści zgłoszenia

Jeśli kiedykolwiek czytałeś/czytałaś o usługach działających w tle, prawdopodobnie natknąłeś/natkniesz się z schematem podobnym 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 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 telefonu komórkowego o niskiej mocy, 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ż rozpocząć pobieranie zasobów 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 wtórne.

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

Odpowiednia chwila na rozpoczęcie 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ść działania na słabszych 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.

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? Może to niektórych zaskoczyć, 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 usługi nie działał 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. Nie ma znaczenia, kiedy jest wywoływany.

Powody, dla których warto zarejestrować się wcześniej

Czy są jakieś sytuacje, w których warto jak najszybciej zarejestrować service workera? 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 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 ramach usługi workera nie prosi o zasoby, które konkurują o przepustowość z prośbami o zasoby 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ż w niej worker usług i pełne pamięci podręczne, nie masz takich samych wrażeń, jak nowy użytkownik, i łatwo 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 (elementy z ikoną koła zębatego obok, pochodzące z elementu obsługi install w usługach działających w tle), przeplatane z żądaniami innych zasobów potrzebnych 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 upewnić się, że 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 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');
    });
}