Tworzenie aplikacji PWA w Google, część 1

Czego zespół Bulletin dowiedział się o skryptach service worker podczas tworzenia aplikacji PWA.

Douglas Parker
Douglas Parker
Joel Riley
Joel Riley
Dikla Cohen
Dikla Cohen

To pierwszy z serii postów na blogu przedstawiających wnioski wyciągnięte przez zespół Google Bulletin podczas tworzenia aplikacji PWA dla użytkowników zewnętrznych. Opowiadamy w niej o wybranych wyzwaniach, podejmowane przez nas działania, aby je przezwyciężyć, oraz ogólne porady na temat unikania pułapek. To nie jest oznacza pełny przegląd aplikacji PWA. Chcemy dzielić się wiedzą zdobytą przez nasz zespół.

W pierwszym poście przedstawimy podstawowe informacje, a następnie omówimy wszystkie czego dowiedzieliśmy się o skryptach service worker.

Tło

Aplikacja Bulletin była rozwijana od połowy 2017 roku do połowy 2019 roku.

Dlaczego zdecydowaliśmy się stworzyć PWA

Zanim przyjrzymy się procesowi programowania, sprawdźmy, dlaczego tworzenie aplikacji PWA było atrakcyjną metodą. opcja dla tego projektu:

  • Możliwość szybkiego wprowadzania poprawek. Jest to szczególnie przydatne, ponieważ narzędzie Bulletin na wielu rynkach.
  • Jeden kod jako baza. Użytkownicy zostali podzieleni mniej więcej po równo między Androida i iOS. PWA oznacza możemy stworzyć jedną aplikację internetową działającą na obu platformach. Pozwoliło to zwiększyć prędkość i wpływ całego zespołu.
  • Aktualizacje są szybkie i niezależne od zachowań użytkowników. Aplikacje PWA mogą automatycznie aktualizować i zmniejsza liczbę nieaktualnych klientów. Udało nam się przenieść problem z backendem i umożliwia bardzo krótki czas migracji w przypadku klientów.
  • Łatwa integracja z aplikacjami własnymi i innych firm. Taka integracja była wymagana dla danej aplikacji. W przypadku aplikacji PWA często oznaczało to samo otwarcie adresu URL.
  • Uproszczone instalowanie aplikacji.

Nasze zasady

W usłudze Bulletin użyliśmy oprogramowania Polymer, ale zasady programu.

Czego dowiedzieliśmy się o skryptach service worker

Nie można mieć aplikacji PWA bez usługi . Skrypty service worker zaawansowane możliwości w zakresie buforowania, funkcje offline, synchronizacja w tle, itp. Chociaż mechanizmy Service Worker znacznie komplikują, to okazało się, że ich korzyści przewyższały dodatkowe korzyści. i jego złożoność.

Wygeneruj ją, jeśli możesz

Unikaj ręcznego pisania skryptu skryptu service worker. Ręczne pisanie mechanizmów Service Worker wymaga ręcznego zarządzania zasobami w pamięci podręcznej i zasadami przepisywania, które są typowe dla większości bibliotek mechanizmów Service Worker, takich jak jako Workbox.

Jednak ze względu na nasz wewnętrzny stos technologiczny nie mogliśmy używać biblioteki do generowania raportów ani zarządzania nimi nasz skrypt service worker. Z naszych wniosków wynika, że Przejdź do sekcji Pitfalls dla niewygenerowane mechanizmy Service Worker, aby dowiedzieć się więcej.

Nie wszystkie biblioteki są zgodne z mechanizmami Service Worker

Niektóre biblioteki JS uruchamiane przez skrypt service worker nie działają zgodnie z oczekiwaniami. Dla: przy założeniu, że dostępne są interfejsy window lub document albo interfejs API jest niedostępny dla usługi instancje robocze (XMLHttpRequest, pamięć lokalna itp.). Upewnij się, że wszystkie krytyczne biblioteki są zgodne z skryptami service worker. W przypadku tej konkretnej aplikacji PWA chcieliśmy użyć gapi.js do uwierzytelniania, a nie Nie można, ponieważ nie obsługiwały mechanizmów Service Worker. Autorzy biblioteki powinni też zmniejszyć lub usunąć stosowanie niepotrzebnych założeń dotyczących kontekstu JavaScriptu tam, gdzie jest to możliwe do obsługi użycia mechanizmu Service Worker , na przykład przez unikanie interfejsów API niezgodnych z mechanizmami Service Worker i unikanie globalnych stanu.

Unikaj dostępu do IndexedDB podczas inicjowania

Nie odczytuj danych IndexedDB, gdy może zainicjować skrypt skryptu service worker. W przeciwnym razie może wystąpić taka niepożądana sytuacja:

  1. Użytkownik ma aplikację internetową w wersji N IndexedDB (IDB)
  2. Nowa aplikacja internetowa została przekazana za pomocą IDB w wersji N+1
  3. Użytkownik otwiera PWA, co uruchamia pobieranie nowego skryptu service worker
  4. Nowy skrypt service worker odczytuje z IDB przed zarejestrowaniem modułu obsługi zdarzeń install, co aktywuje Cykl uaktualniania IDB z trybu N do N+1
  5. Użytkownik ma starego klienta w wersji N, dlatego proces uaktualniania skryptu service worker zawiesza się jako aktywny połączenia ze starą wersją bazy danych są nadal otwarte
  6. Skrypt service worker zawiesza się i nigdy nie instaluje

W naszym przypadku pamięć podręczna została unieważniona podczas instalacji skryptu service worker, jeśli więc skrypt service worker nigdy użytkownicy nie otrzymali zaktualizowanej aplikacji.

Zadbaj o odporność

Skrypty mechanizmu Service Worker uruchamiają się w tle, ale mogą zostać zakończone w każdej chwili, nawet w trakcie operacji wejścia-wyjścia (sieć, IDB itp.). Każdy długotrwały proces powinien możliwość wznowienia w dowolnym momencie.

W przypadku procesu synchronizacji, który powodował przesyłanie dużych plików na serwer i zapisanie go w IDB, funkcji przesyłania częściowego przesyłania zostało przerwane, aby skorzystać z funkcji wznawiania przesyłania w wewnętrznej bibliotece przesyłania. system, zapisując możliwy do wznowienia adres URL przesyłania w IDB przed rozpoczęciem przesyłania i używając tego adresu do wznawiania przesłać, jeśli nie zakończy się za pierwszym razem. Również przed długotrwałą operacją wejścia-wyjścia stan został zapisany w IDB, aby wskazać, na jakim etapie procesu się znajdujemy.

Nie zależą od stanu globalnego

Skrypty service worker występują w innym kontekście, więc wiele symboli nie istnieje obecnie. Duża część naszego kodu została uruchomiona zarówno w kontekście window, jak i kontekście mechanizmu Service Worker (takiego takie jak logowanie, flagi, synchronizacja itp.). Kod musi obronić usługi, z których korzysta. Są to na przykład: pamięci lokalnej ani plików cookie. Za pomocą globalThis aby odwoływać się do obiektu globalnego w sposób, który będzie działać we wszystkich kontekstach. Użyj też zapisanych danych zmiennymi globalnymi, ponieważ nie ma gwarancji, kiedy skrypt zostanie wyłączony, skasowany przez państwo.

Programowanie lokalne

Głównym składnikiem mechanizmów Service Worker jest możliwe lokalne buforowanie zasobów. Jednak w trakcie opracowywania przeciwieństwem tego, czego oczekujesz, zwłaszcza gdy aktualizacje są wprowadzane leniwie. Nadal chcesz z naszego serwera, aby można było debugować problemy lub używać innych interfejsów API, synchronizacji w tle ani powiadomień. W Chrome możesz to zrobić za pomocą Narzędzi deweloperskich w Chrome, zaznaczając pole wyboru Pomijaj dla sieci (panel Aplikacja > panel Skrypty robocze) w a także zaznaczyć pole wyboru Wyłącz pamięć podręczną w panelu Sieć, aby wyłączyć pamięć podręczną. Aby objąć nią więcej przeglądarek, zdecydowaliśmy się wybrać inne rozwiązanie, łącznie z flagą umożliwiającą wyłączenie buforowania w naszym mechanizmie Service Worker, który jest domyślnie włączony na do tworzenia kampanii. Dzięki temu deweloperzy zawsze uzyskują najnowsze zmiany bez problemów z buforowaniem. Jest ważne jest uwzględnienie nagłówka Cache-Control: no-cache, a także uniemożliwianie przeglądarce buforowanie zasobów.

Latarnia morska

Lighthouse udostępnia wiele funkcji debugowania przydatne w przypadku PWA. Skanuje witrynę i generuje raporty dotyczące progresywnych aplikacji internetowych, wydajności, ułatwień dostępu, SEO i innych sprawdzonych metod. Zalecamy uruchamianie Lighthouse w trybie ciągłym , aby powiadamiać Cię o uszkodzeniu jednej z poniższych kryteria kwalifikacji jako aplikacji PWA. Zdarzało się to już u nas, ponieważ skrypt service worker nie instaluje się Nie spodziewaliśmy się tego przed rozpoczęciem produkcji. Wdrożenie Lighthouse w ramach CI to pomogło.

Korzystaj z ciągłego dostarczania

Skrypty service worker mogą się automatycznie aktualizować, więc użytkownicy nie mają możliwości ograniczenia uaktualnień. Ten znacznie zmniejsza liczbę nieaktualnych klientów działających w naturalny sposób. Gdy użytkownik otworzy aplikację, skrypt service worker obsługuje starego klienta, podczas gdy leniwie pobiera nowego klienta. Gdy funkcja nowy klient, użytkownik zobaczy prośbę o odświeżenie strony w celu uzyskania dostępu do nowych funkcji. Nawet jeśli użytkownik zignorował to żądanie, ale przy następnym odświeżeniu strony użytkownik zobaczy nowy wersję klienta. Dlatego użytkownikom trudno jest odmówić w przypadku aplikacji na iOS i Androida.

Udało nam się wprowadzić zmiany powodujące niezgodność w backendzie w krótkim czasie klientów. Zazwyczaj dajemy użytkownikom miesiąc na aktualizację do nowszej wersji, zanim zmian powodujących niezgodność. Ponieważ aplikacja wyświetlałaby nieaktualne reklamy, w przypadku starszych klientów było to możliwe. nie muszą być aktywne, jeśli użytkownik nie uruchamiał aplikacji przez dłuższy czas. W iOS mechanizmy Service Worker są został usunięty po kilku tygodniach więc taka sytuacja nie ma miejsca. W przypadku Androida ten problem może zmniejszyć nieaktualne lub tracą ważność ręcznie po kilku tygodniach. W praktyce nigdy z nieaktualnych klientów. Dokładność, jaką zespół chce osiągnąć, zależy od jego konkretnego zastosowania. ale aplikacje PWA zapewniają znacznie większą elastyczność niż aplikacje na iOS/Androida.

Uzyskiwanie wartości plików cookie w skrypcie service worker

Czasami dostęp do wartości plików cookie w kontekście mechanizmu Service Worker jest konieczne. W naszym przypadku niezbędne do uzyskania dostępu do wartości plików cookie w celu wygenerowania tokena do uwierzytelniania własnych żądań do interfejsu API. W skrypt service worker, synchroniczne interfejsy API, takie jak document.cookies, są niedostępne. W każdej chwili możesz wysłać do aktywnych (okienowanych) klientów z mechanizmu Service Worker z prośbą o wartości plików cookie, skrypt service worker może działać w tle bez żadnego klienta w oknie np. podczas synchronizacji w tle. Aby obejść ten problem, utworzyliśmy punkt końcowy który po prostu odebrał wartość pliku cookie klientowi. Skrypt service worker żądania sieciowe do tego punktu końcowego i odczytać odpowiedź, aby uzyskać wartości plików cookie.

Wraz z udostępnieniem Cookie Store API to obejście nie powinno być już konieczne w przypadku przeglądarek, które go obsługują, asynchroniczny dostęp do plików cookie przeglądarki i może być używany bezpośrednio przez mechanizm Service Worker.

Problemy związane z niewygenerowanymi mechanizmami Service Worker

Sprawdź, czy skrypt skryptu service worker zmienia się w przypadku zmiany dowolnego statycznego pliku w pamięci podręcznej

Typowym wzorcem PWA jest instalowanie przez skrypt service worker wszystkich statycznych plików aplikacji faza install, która umożliwia klientom bezpośrednie trafienie do pamięci podręcznej interfejsu Cache Storage API dla wszystkich kolejne odwiedziny . Skrypty service worker są instalowane tylko wtedy, gdy przeglądarka wykryje, że usługa w jakiś sposób zmienił się skrypt instancji roboczej, więc musieliśmy się upewnić, że sam plik skryptu service worker zostało zmienione w jakiś sposób po zmianie pliku w pamięci podręcznej. Zrobiliśmy to ręcznie przez umieszczenie skrótu statyczny zbiór plików zasobów w ramach skryptu service worker, w wyniku czego każda wersja generuje osobny JavaScript service worker. Biblioteki instancji Service Worker, takie jak Workbox automatyzuje ten proces za Ciebie.

Testowanie jednostkowe

Interfejsy API mechanizmu Service Worker można wykonać, dodając detektory zdarzeń do obiektu globalnego. Na przykład:

self.addEventListener('fetch', (evt) => evt.respondWith(fetch('/foo')));

Testowanie może być trudne, ponieważ trzeba imitować regułę zdarzenia, czyli obiekt zdarzenia, wywołanie zwrotne respondWith(), a następnie poczekaj na obietnicę, zanim w końcu potwierdzisz wynik. An łatwiejszym sposobem jest przekazanie całej implementacji do innego pliku. i testowania modelu.

import fetchHandler from './fetch_handler.js';
self.addEventListener('fetch', (evt) => evt.respondWith(fetchHandler(evt)));

Ze względu na trudności związane z testowaniem jednostkowym skryptu skryptu service worker zachowywaliśmy pracownika usługi podstawowej skrypt w jak najprostszy sposób, dzieląc większość implementacji na pozostałe moduły. Od te pliki były tylko standardowymi modułami JS, łatwiej można je było przetestować w ramach jednego biblioteki.

Wkrótce udostępnimy część 2 i 3

W częściach 2. i 3. tej serii zajmiemy się zarządzaniem multimediami i problemami związanymi z iOS. Jeśli Jeśli chcesz dowiedzieć się więcej o tworzeniu aplikacji PWA w Google, odwiedź nasze profile autora, skontaktuj się z nami: