okno-skrzynki roboczej

Pakiet workbox-window to zestaw modułów, które są uruchamiane w kontekście window, czyli na stronach internetowych. Stanowią one uzupełnienie innych pakietów pudełek roboczych, które działają w skrypcie service worker.

Najważniejsze cechy/cele workbox-window to:

Importowanie i używanie okna skrzynki roboczej

Podstawowym punktem wejścia dla pakietu workbox-window jest klasa Workbox. Możesz ją zaimportować do swojego kodu z naszej sieci CDN lub za pomocą popularnych narzędzi do łączenia skryptów JavaScript.

Korzystanie z naszej sieci CDN

Najprostszym sposobem na zaimportowanie klasy Workbox do swojej witryny jest z naszej sieci CDN:

<script type="module">
  import {Workbox} from 'https://storage.googleapis.com/workbox-cdn/releases/6.4.1/workbox-window.prod.mjs';

  if ('serviceWorker' in navigator) {
    const wb = new Workbox('/sw.js');

    wb.register();
  }
</script>

Zwróć uwagę, że w tym przykładzie do wczytywania klasy Workbox użyto <script type="module"> i instrukcji import. Chociaż może się wydawać, że kod ten trzeba przetranspilować, by działał w starszych przeglądarkach, w rzeczywistości nie jest to jednak konieczne.

Wszystkie najpopularniejsze przeglądarki, które obsługują mechanizmy Service Worker, obsługują też natywne moduły JavaScript, więc ten kod można przesłać w dowolnej przeglądarce (starsze przeglądarki po prostu go ignorują).

Wczytuję zawartość skrzynki roboczej za pomocą pakietów JavaScript

Chociaż do korzystania z workbox-window nie jest absolutnie żadne narzędzie, nie musisz używać żadnych narzędzi, ale jeśli Twoja infrastruktura programistyczna zawiera już pakiet SDK, taki jak webpack lub Rollup, który obsługuje zależności npm, możesz ich używać do wczytywania workbox-window.

Pierwszym krokiem jest zainstalowanie workbox-window jako zależności aplikacji:

npm install workbox-window

Następnie w jednym z plików JavaScript aplikacji import pole robocze, odnosząc się do nazwy pakietu workbox-window:

import {Workbox} from 'workbox-window';

if ('serviceWorker' in navigator) {
  const wb = new Workbox('/sw.js');

  wb.register();
}

Jeśli Twój pakiet SDK obsługuje dzielenie kodu za pomocą instrukcji dynamicznego importu, możesz też warunkowo wczytywać pakiet workbox-window, co powinno zmniejszyć rozmiar głównego pakietu na stronie.

Mimo że zasób workbox-window jest niewielki, nie ma powodu, dla którego musi być przeładowywana w podstawową logikę aplikacji w witrynie. Skrypty service worker z natury są postępowymi ulepszeniami.

if ('serviceWorker' in navigator) {
  const {Workbox} = await import('workbox-window');

  const wb = new Workbox('/sw.js');
  wb.register();
}

Zaawansowane koncepcje grupowania

W przeciwieństwie do pakietów Workbox uruchamianych w skrypcie service worker pliki kompilacji, do których odwołują się pola main i module w package.json w polu workbox-window, są transpilowane do wersji ES5. Dzięki temu są one zgodne z współczesnymi narzędziami do tworzenia, a niektóre z nich nie umożliwiają deweloperom transpilacji żadnych zależności node_module.

Jeśli Twój system kompilacji umożliwia transpilację zależności (lub jeśli nie musisz transpilować żadnego kodu), lepiej jest zaimportować konkretny plik źródłowy zamiast samego pakietu.

Oto różne sposoby importowania danych Workbox i wyjaśnienie, co zwraca każdy z nich:

// Imports a UMD version with ES5 syntax
// (pkg.main: "build/workbox-window.prod.umd.js")
const {Workbox} = require('workbox-window');

// Imports the module version with ES5 syntax
// (pkg.module: "build/workbox-window.prod.es5.mjs")
import {Workbox} from 'workbox-window';

// Imports the module source file with ES2015+ syntax
import {Workbox} from 'workbox-window/Workbox.mjs';

Przykłady

Po zaimportowaniu klasy Workbox możesz jej użyć do zarejestrowania się i interakcji z skryptem service worker. Oto kilka przykładów wykorzystania właściwości Workbox w aplikacji:

Zarejestruj skrypt service worker i powiadom użytkownika przy pierwszym uruchomieniu tego skryptu

Wiele aplikacji internetowych umożliwia wstępne zapisywanie zasobów w pamięci podręcznej, dzięki czemu aplikacja może działać w trybie offline przy kolejnych wczytywaniach stron. W niektórych przypadkach warto poinformować użytkownika, że aplikacja jest teraz dostępna offline.

const wb = new Workbox('/sw.js');

wb.addEventListener('activated', event => {
  // `event.isUpdate` will be true if another version of the service
  // worker was controlling the page when this version was registered.
  if (!event.isUpdate) {
    console.log('Service worker activated for the first time!');

    // If your service worker is configured to precache assets, those
    // assets should all be available now.
  }
});

// Register the service worker after event listeners have been added.
wb.register();

Powiadom użytkownika, jeśli skrypt service worker został zainstalowany, ale utknął na etapie oczekiwania na aktywację

Gdy strona kontrolowana przez istniejący mechanizm Service Worker zarejestruje nowy skrypt service worker, domyślnie nie aktywuje się on, dopóki wszystkie klienty kontrolowane przez ten skrypt service worker nie zostaną w pełni wyładowane.

Jest to częsty problem dla programistów, zwłaszcza w przypadkach, gdy ponowne wczytanie bieżącej strony nie powoduje aktywowania nowego skryptu service worker.

Aby zminimalizować nieporozumienia i wyjaśnić, kiedy występuje taka sytuacja, klasa Workbox udostępnia zdarzenie waiting, na które możesz nasłuchiwać:

const wb = new Workbox('/sw.js');

wb.addEventListener('waiting', event => {
  console.log(
    `A new service worker has installed, but it can't activate` +
      `until all tabs running the current version have fully unloaded.`
  );
});

// Register the service worker after event listeners have been added.
wb.register();

Powiadamiaj użytkownika o aktualizacjach pamięci podręcznej pakietu workbox-broadcast-update

Pakiet workbox-broadcast-update to świetny sposób na wyświetlanie treści z pamięci podręcznej (aby szybko je przesłać), a jednocześnie umożliwia informowanie użytkownika o aktualizacjach treści (za pomocą strategii nieaktualnej w trakcie ponownej weryfikacji).

Aby otrzymywać te powiadomienia z poziomu okna, możesz nasłuchiwać zdarzeń message typu CACHE_UPDATED:

const wb = new Workbox('/sw.js');

wb.addEventListener('message', event => {
  if (event.data.type === 'CACHE_UPDATED') {
    const {updatedURL} = event.data.payload;

    console.log(`A newer version of ${updatedURL} is available!`);
  }
});

// Register the service worker after event listeners have been added.
wb.register();

Wyślij do skryptu service worker listę adresów URL do pamięci podręcznej

W przypadku niektórych aplikacji można poznać wszystkie zasoby, które muszą być wstępnie zapisane w pamięci podręcznej w czasie kompilacji, ale niektóre wyświetlają zupełnie inne strony, w zależności od adresu URL, na który użytkownik trafia jako pierwszy.

W przypadku aplikacji z drugiej kategorii sensowne może być zapisywanie w pamięci podręcznej tylko tych zasobów, które są potrzebne użytkownikowi w przypadku konkretnej strony, którą odwiedził. Gdy używasz pakietu workbox-routing, możesz wysłać do routera listę adresów URL do pamięci podręcznej, która będzie zapisywać te adresy w pamięci podręcznej zgodnie z regułami określonymi na routerze.

W tym przykładzie za każdym razem, gdy aktywowany jest nowy skrypt service worker, do routera jest wysyłana lista adresów URL wczytywanych przez stronę. Uwaga: możesz wysyłać wszystkie adresy URL, ponieważ w pamięci podręcznej będą przechowywane tylko te adresy, które pasują do zdefiniowanej trasy w skryptu service worker:

const wb = new Workbox('/sw.js');

wb.addEventListener('activated', event => {
  // Get the current page URL + all resources the page loaded.
  const urlsToCache = [
    location.href,
    ...performance.getEntriesByType('resource').map(r => r.name),
  ];
  // Send that list of URLs to your router in the service worker.
  wb.messageSW({
    type: 'CACHE_URLS',
    payload: {urlsToCache},
  });
});

// Register the service worker after event listeners have been added.
wb.register();

Ważne momenty cyklu życia skryptu service worker

Cykl życia mechanizmów Service Worker jest złożony i może stanowić wyzwanie. Jest to m.in. tak złożony charakter, że musi obsługiwać wszystkie przypadki brzegowe dla wszystkich możliwych zastosowań skryptu service worker (np. rejestracja więcej niż jednego skryptu service worker, rejestracja różnych instancji roboczych w różnych ramkach, rejestracja instancji roboczych o różnych nazwach).

Większość deweloperów implementujących mechanizmy Service Worker nie powinna jednak martwić się o te skrajne przypadki, ponieważ ich zastosowanie jest dość proste. Większość programistów rejestruje tylko 1 skrypt service worker na wczytanie strony i nie zmienia nazwy tego skryptu wdrażanego na serwerze.

Klasa Workbox uwzględnia ten prostszy widok cyklu życia mechanizmów Service Worker, dzieląc wszystkie rejestracje tych instancji na 2 kategorie: własną instancję, zarejestrowany skrypt service worker i zewnętrzny skrypt service worker:

  • Zarejestrowany skrypt service worker: skrypt service worker, który rozpoczął instalację w wyniku wywołania przez instancję Workbox wywołania register() lub już aktywnego skryptu service worker, jeśli wywołanie register() nie wywołało zdarzenia updatefound podczas rejestracji.
  • Zewnętrzny skrypt service worker: skrypt service worker, który rozpoczął instalację niezależnie od instancji Workbox wywołującej metodę register(). Dzieje się tak zazwyczaj wtedy, gdy nowa wersja Twojej witryny jest otwarta na innej karcie. Jeśli zdarzenie pochodzi z zewnętrznego skryptu service worker, jego właściwość isExternal zostanie ustawiona na true.

Biorąc pod uwagę te 2 rodzaje mechanizmów Service Worker, poniżej znajdziesz zestawienie wszystkich ważnych momentów cyklu życia tych mechanizmów oraz zalecenia dla deweloperów dotyczące ich obsługi:

Przy pierwszej instalacji skryptu service worker

Przy pierwszej instalacji mechanizmu Service Worker prawdopodobnie lepiej traktować wszystkie przyszłe aktualizacje.

W workbox-window możesz odróżnić pierwszą instalację od przyszłych aktualizacji, sprawdzając właściwość isUpdate w dowolnym z poniższych zdarzeń. Przy pierwszej instalacji isUpdate będzie mieć wartość false.

const wb = new Workbox('/sw.js');

wb.addEventListener('installed', event => {
  if (!event.isUpdate) {
    // First-installed code goes here...
  }
});

wb.register();
Wyjątkowe chwile Zdarzenie Zalecane działanie
Nowy skrypt service worker został zainstalowany (po raz pierwszy) installed

Przy pierwszej instalacji skryptu service worker często umieszcza się w pamięci podręcznej wszystkie zasoby potrzebne do działania witryny w trybie offline. Warto poinformować użytkownika, że jego strona może teraz działać w trybie offline.

Co więcej, przy pierwszym zainstalowaniu skryptu service worker nie przechwyci on zdarzeń pobierania podczas wczytywania strony, dlatego warto rozważyć buforowanie zasobów, które zostały już wczytane (chociaż nie jest to wymagane, jeśli zasoby są już w pamięci podręcznej). Jak to zrobić w przykładzie powyżej wyślij listę adresów URL do pamięci podręcznej

Skrypt service worker zaczął kontrolować stronę controlling

Po zainstalowaniu nowego skryptu service worker i rozpoczęciu kontroli nad stroną wszystkie kolejne zdarzenia pobierania będą przechodzić przez ten skrypt. Jeśli Twój skrypt service worker dodaje specjalną logikę do obsługi określonego zdarzenia pobierania, w tym momencie masz pewność, że zadziała logika.

Pamiętaj, że przy pierwszym zainstalowaniu skryptu service worker nie rozpocznie on kontroli nad bieżącą stroną, chyba że wywoła on clients.claim() w zdarzeniu aktywacji. Domyślnym zachowaniem jest oczekiwanie do następnego wczytania strony w celu rozpoczęcia kontroli.

Z perspektywy workbox-window oznacza to, że zdarzenie controlling jest wysyłane tylko wtedy, gdy skrypt service worker wywołuje metodę clients.claim(). To zdarzenie nie jest wysyłane, jeśli strona była już kontrolowana przed rejestracją.

Skrypt service worker zakończył aktywację activated

Jak już wspomnieliśmy, za pierwszym razem, gdy mechanizm Service Worker zakończy aktywację, mógł (ale nie musi) zacząć kontrolować stronę.

Dlatego nie należy nasłuchiwać zdarzeń aktywowania, aby dowiedzieć się, kiedy skrypt service worker ma kontrolę nad stroną. Jeśli jednak uruchamiasz logikę w aktywnym zdarzeniu (w skryptach service worker) i musisz wiedzieć, kiedy ta logika zostanie zakończona, aktywowane zdarzenie będzie Cię o tym informować.

Znaleziono zaktualizowaną wersję skryptu service worker

Gdy rozpocznie się instalowanie nowego skryptu service worker, ale strona będzie już sterowana przez istniejącą wersję, właściwość isUpdate wszystkich następujących zdarzeń będzie miała wartość true.

Twoja reakcja w takiej sytuacji zwykle różni się od reakcji na pierwszej instalacji, ponieważ musisz decydować, kiedy i jak użytkownik otrzyma tę aktualizację.

Wyjątkowe chwile Zdarzenie Zalecane działanie
Zainstalowano nowy skrypt service worker (aktualizujący poprzedni) installed

Jeśli nie jest to pierwsza instalacja skryptu service worker (event.isUpdate === true), oznacza to, że znaleziono i zainstalowano jego nowszą wersję (czyli inną wersję niż ta, która obecnie steruje stroną).

Zwykle oznacza to, że na serwerze została wdrożona nowsza wersja witryny, a nowe zasoby mogły właśnie zakończyć zapisywanie w pamięci podręcznej.

Uwaga: niektórzy deweloperzy używają zdarzenia installed, aby informować użytkowników o nowej wersji ich witryny. Jednak w zależności od tego, czy wywołasz skipWaiting() w skrypcie service worker, zainstalowany skrypt service worker może od razu zostać aktywowany, ale nie musi. Jeśli wywołujesz metodę skipWaiting(), najlepiej poinformować użytkowników o aktualizacji po aktywacji nowego skryptu service worker. Jeśli nie wywołasz funkcji skipWaiting, lepiej poinformować ich o oczekującej aktualizacji w zdarzeniu oczekiwania (więcej szczegółów znajdziesz poniżej).

Skrypt service worker został zainstalowany, ale utknął na etapie oczekiwania waiting

Jeśli zaktualizowana wersja skryptu service worker podczas instalacji nie wywoła skipWaiting(), nie zostanie ona aktywowana, dopóki nie zostaną wyładowane wszystkie strony kontrolowane przez ten aktywny mechanizm Service Worker. Poinformuj użytkownika o dostępnej aktualizacji, która zostanie zastosowana przy następnej wizycie.

Ostrzeżenie! Deweloperzy często proszą użytkowników o pobranie nowej wersji, ale w wielu przypadkach odświeżenie strony nie aktywuje zainstalowanej instancji roboczej. Jeśli użytkownik odświeży stronę, a skrypt service worker wciąż czeka, zdarzenie waiting uruchomi się ponownie, a właściwość event.wasWaitingBeforeRegister będzie mieć wartość prawda. Planujemy ulepszyć tę funkcję w kolejnej wersji. Postępuj zgodnie z problemem nr 1848, aby być na bieżąco.

Możesz też zapytać użytkownika, czy chce pobrać aktualizację, czy dalej czekać. Jeśli zdecydujesz się pobrać aktualizację, możesz użyć polecenia postMessage(), by nakazać skryptowi service worker uruchomienie skipWaiting(). Przykładowy przepis znajdziesz w zaawansowanym przepisie: zaproponuj użytkownikom ponowne załadowanie strony.

Skrypt service worker zaczął kontrolować stronę controlling

Gdy zaktualizowany skrypt service worker zaczyna kontrolować stronę, oznacza to, że aktualnie sterowana wersja tego skryptu jest inna niż wersja, która pozostawała pod kontrolą podczas wczytywania strony. W niektórych przypadkach może to być prawidłowe, ale może też oznaczać, że niektóre zasoby, do których odwołuje się bieżąca strona, nie są już w pamięci podręcznej (prawdopodobnie też nie są na serwerze). Warto poinformować użytkownika, że niektóre elementy strony mogą nie działać prawidłowo.

Uwaga: zdarzenie controlling nie zostanie uruchomione, jeśli nie wywołasz parametru skipWaiting() w skryptach service worker.

Skrypt service worker zakończył aktywację activated Gdy zaktualizowany skrypt service worker zakończy aktywację, oznacza to, że wszystkie logiki uruchomione w jego obiekcie activate zostały ukończone. Jeśli jest coś, co musisz odłożyć do czasu, aż logika zostanie zakończona, możesz to zrobić.

Znaleziono nieoczekiwaną wersję skryptu service worker

Czasami użytkownicy przez bardzo długi czas pozostawili witrynę otwartą na karcie w tle. Mogą nawet otworzyć nową kartę i przejść do witryny, nie zdając sobie sprawy, że jest ona już otwarta na karcie w tle. W takich przypadkach możliwe jest jednoczesne korzystanie z 2 wersji witryny, co może stanowić problem dla Ciebie jako dewelopera.

Przeanalizujmy scenariusz, w którym masz kartę A z witryną w wersji 1 i kartę B z wersją 2. Po wczytaniu karty B będzie ona kontrolowana przez wersję skryptu service worker, która była dostępna w wersji 1, ale strona zwracana przez serwer (jeśli w przypadku żądań nawigacji używasz strategii buforowania opartej na sieci) będzie zawierać wszystkie zasoby wersji 2.

Zazwyczaj nie jest to jednak problem w przypadku karty B, ponieważ podczas tworzenia kodu w wersji 2 wiadomo było, jak działa kod w wersji 1. Może to jednak powodować problemy w przypadku karty A, ponieważ Twój kod w wersji 1 nie byłby w stanie przewidzieć,jakie zmiany może on wprowadzić.

Aby ułatwić obsługę takich sytuacji, workbox-window wysyła też zdarzenia cyklu życia, gdy wykryje aktualizację z „zewnętrznego” skryptu service worker, gdzie „zewnętrzna” oznacza każdą wersję, która nie jest wersją bieżącą instancji Workbox.

Od wersji Workbox w wersji 6 i nowszych te zdarzenia odpowiadają zdarzeniom opisanym powyżej, ale z dodaną właściwością isExternal: true ustawioną w każdym obiekcie zdarzenia. Jeśli Twoja aplikacja internetowa wymaga zaimplementowania określonej logiki do obsługi „zewnętrznego” skryptu service worker, możesz sprawdzić tę właściwość w modułach obsługi zdarzeń.

Unikanie typowych błędów

Jedną z najbardziej przydatnych funkcji Workbox jest logowanie programistów. Dotyczy to zwłaszcza workbox-window.

Wiemy, że programowanie z wykorzystaniem mechanizmów Service Worker często bywa niejasnych, a jeśli dzieje się coś sprzecznego z oczekiwaniami, trudno jest stwierdzić, z czego to wynika.

Jeśli na przykład wprowadzisz zmianę w skrypcie service worker i załadujesz stronę ponownie, możesz nie zobaczyć tej zmiany w przeglądarce. Najbardziej prawdopodobną przyczyną jest to, że mechanizm Service Worker wciąż czeka na aktywację.

Gdy jednak zarejestrujesz skrypt service worker za pomocą klasy Workbox, w konsoli programisty będziesz otrzymywać informacje o wszystkich zmianach stanu cyklu życia, co powinno ułatwić debugowanie, dlaczego wszystko działa niezgodnie z oczekiwaniami.

Ostrzeżenie w konsoli okna roboczego dla instancji roboczej

Oprócz tego częsty błąd, jaki programiści popełniają przy pierwszym użyciu skryptu service worker, polega na zarejestrowaniu go w niewłaściwym zakresie.

Aby temu zapobiec, klasa Workbox ostrzeże Cię, jeśli strona rejestrująca skrypt service worker nie znajduje się w jego zakresie. Jeśli skrypt service worker jest aktywny, ale jeszcze nie kontroluje strony, pojawi się ostrzeżenie:

Ostrzeżenie o konsoli okna roboczego dla instancji roboczej, która nie ma kontroli

Okno do komunikacji między skryptem service worker

Najbardziej zaawansowane wykorzystanie skryptu service worker obejmuje wiele komunikatów między nim a oknem. Klasa Workbox pomaga też w tym, udostępniając metodę messageSW(), która postMessage() spowoduje postMessage() zarejestrowany skrypt service worker instancji i będzie czekać na odpowiedź.

Możesz wysyłać dane do skryptu service worker w dowolnym formacie, ale format udostępniany przez wszystkie pakiety Workbox jest obiektem z 3 właściwościami (2 ostatnie są opcjonalne):

Właściwość Wymagana? Typ Opis
type Yes string

Unikalny ciąg identyfikujący tę wiadomość.

Zgodnie z konwencją typy pisane są wielkimi literami, a słowa rozdzielają podkreśleniami. Jeśli typ reprezentuje działanie do wykonania, powinno być to polecenie w czasie rzeczywistym (np. CACHE_URLS). Jeśli typ reprezentuje zgłaszane informacje, powinno być w czasie przeszłym (np. URLS_CACHED).

meta nie string W Workbox jest to zawsze nazwa pakietu Workbox, z którego wysłano wiadomość. Podczas wysyłania wiadomości samodzielnie możesz pominąć tę właściwość lub ustawić ją w dowolny sposób.
payload nie * Wysyłane dane. Zwykle jest to obiekt, ale nie musi.

W przypadku wiadomości wysyłanych za pomocą metody messageSW() używany jest MessageChannel, aby odbiorca mógł na nie odpowiadać. Aby odpowiedzieć na wiadomość, możesz zadzwonić pod numer event.ports[0].postMessage(response) za pomocą detektora. Metoda messageSW() zwraca obietnicę, która odnosi się do dowolnego elementu response, którego użyjesz w odpowiedzi.

Oto przykład wysyłania wiadomości z okna do skryptu service worker i uzyskiwania odpowiedzi. Pierwszy blok kodu to odbiornik wiadomości w skrypcie service worker, a drugi używa klasy Workbox do wysyłania wiadomości i oczekiwania na odpowiedź:

Kod w pliku sw.js:

const SW_VERSION = '1.0.0';

addEventListener('message', event => {
  if (event.data.type === 'GET_VERSION') {
    event.ports[0].postMessage(SW_VERSION);
  }
});

Kod w pliku main.js (uruchamiany w oknie):

const wb = new Workbox('/sw.js');
wb.register();

const swVersion = await wb.messageSW({type: 'GET_VERSION'});
console.log('Service Worker version:', swVersion);

Zarządzanie niezgodnością wersji

Powyższy przykład pokazuje, jak możesz wdrożyć sprawdzanie wersji skryptu service worker z okna. Ten przykład pokazujemy w przykładzie, ponieważ gdy wysyłasz wiadomości między oknem a mechanizmem Service Worker, pamiętaj, że może on nie korzystać z tej samej wersji witryny, w której działa kod strony. Rozwiązanie tego problemu różni się w zależności od tego, czy obsługujesz strony najpierw w sieci czy na bazie pamięci podręcznej.

Najpierw sieć

Jeśli wyświetlasz najpierw sieć stron, użytkownicy będą zawsze otrzymywać najnowszą wersję kodu HTML z Twojego serwera. Gdy jednak użytkownik po raz pierwszy odwiedzi Twoją witrynę (po wdrożeniu aktualizacji), otrzyma kod HTML z najnowszej wersji, ale mechanizm Service Worker uruchomiony w przeglądarce będzie już wersją zainstalowaną wcześniej (prawdopodobnie wiele starszych wersji).

Pamiętaj o tym, że jeśli JavaScript wczytany przez bieżącą wersję strony wysyła komunikat do starszej wersji Twojego skryptu service worker, ta wersja może nie wiedzieć, jak odpowiedzieć (lub może odpowiadać w niezgodnym formacie).

Dlatego przed podjęciem jakichkolwiek działań warto zawsze utworzyć wersję skryptu service worker i sprawdzić, czy są zgodne.

Na przykład w powyższym kodzie, jeśli wersja mechanizmu Service Worker zwrócona przez to wywołanie messageSW() jest starsza niż oczekiwana, należy poczekać na aktualizację (co powinno nastąpić w przypadku wywołania register()). W tym momencie możesz powiadomić użytkownika lub zaktualizować aktualizację lub ręcznie pominąć fazę oczekiwania, aby od razu aktywować nowy skrypt service worker.

Najpierw z pamięci podręcznej

W przeciwieństwie do stron udostępnianych najpierw w sieci, gdy serwer udostępnia strony z pamięci podręcznej, wiadomo, że początkowo wersja strony będzie zawsze dostępna w tej samej wersji co skrypt service worker (ponieważ to właśnie go wyświetla). Dlatego można od razu używać messageSW().

Jeśli jednak zostanie znaleziona zaktualizowana wersja mechanizmu Service Worker i zostanie aktywowana, gdy strona wywoła metodę register() (czyli celowo pominiesz etap oczekiwania), wysyłanie do niej wiadomości może już nie być bezpieczne.

Jedną ze strategii zarządzania tą możliwością jest zastosowanie schematu obsługi wersji, który pozwala na odróżnienie aktualizacji powodujących niezgodność od tych, które nie powodują uszkodzenia. W przypadku awarii aktualizacji wiadomo, że wysyłanie wiadomości do mechanizmu Service Worker nie jest bezpieczne. Zamiast tego warto ostrzec użytkownika, że korzysta ze starej wersji strony, i zalecić ponowne załadowanie strony w celu uzyskania aktualizacji.

Pomiń oczekiwanie asystenta

Typowa konwencja użycia komunikacji okna do mechanizmu Service Worker polega na wysyłaniu wiadomości {type: 'SKIP_WAITING'}, która informuje zainstalowany mechanizm Service Worker w celu pominięcia fazy oczekiwania i aktywowania.

Począwszy od Workbox w wersji 6 metoda messageSkipWaiting() może służyć do wysyłania wiadomości {type: 'SKIP_WAITING'} do oczekującego skryptu service worker powiązanego z bieżącą rejestracją tego skryptu. Jeśli nie ma oczekującego skryptu service worker, nie wykonuje on żadnych działań.

Typy

Workbox

Klasa ułatwiająca obsługę rejestracji, aktualizacji i reagowania na zdarzenia cyklu życia mechanizmów Service Worker.

Właściwości

  • konstruktor

    void

    Tworzy nową instancję Workbox z adresem URL skryptu i opcjami skryptu service worker. Adres URL skryptu i opcje są takie same jak użyte przy wywołaniu funkcji navigator.serviceWorker.register(scriptURL, options).

    Funkcja constructor wygląda tak:

    (scriptURL: string|TrustedScriptURL,registerOptions?: object)=> {...}

    • scriptURL

      string|TrustedScriptURL

      Skrypt skryptu service worker powiązany z tą instancją. TrustedScriptURL jest obsługiwany.

    • registerOptions

      obiekt opcjonalnie

  • aktywna

    Promise<ServiceWorker>

  • sterowanie

    Promise<ServiceWorker>

  • getSW

    void

    Kończy się z odniesieniem do skryptu service worker pasującego do adresu URL skryptu tej instancji, gdy tylko będzie dostępny.

    Jeśli w momencie rejestracji istnieje już aktywny lub oczekujący skrypt service worker z pasującym adresem URL skryptu, używany będzie ten skrypt (oczekujący skrypt service worker ma pierwszeństwo przed aktywnym skryptem service worker, jeśli oba są spełnione, bo taki skrypt zostałby zarejestrowany niedawno). Jeśli w momencie rejestracji nie ma pasującego aktywnego lub oczekującego skryptu service worker, obietnica nie zostanie zrealizowana, dopóki nie zostanie odnaleziona aktualizacja i nie rozpocznie się jej instalacja, co oznacza, że używany jest mechanizm instalacyjny.

    Funkcja getSW wygląda tak:

    ()=> {...}

    • returns

      Promise<ServiceWorker>

  • messageSW

    void

    Wysyła przekazany obiekt danych do skryptu service worker zarejestrowanego przez tę instancję (za pomocą workbox-window.Workbox#getSW) i zwraca odpowiedź (jeśli została wysłana).

    Odpowiedź można ustawić w module obsługi wiadomości w skrypcie service worker, wywołując metodę event.ports[0].postMessage(...), co spowoduje zrealizowanie obietnicy zwróconej przez metodę messageSW(). Jeśli nie otrzymasz odpowiedzi, obietnica nigdy nie zostanie rozwiązana.

    Funkcja messageSW wygląda tak:

    (data: object)=> {...}

    • dane

      obiekt

      Obiekt do wysłania do skryptu service worker

    • returns

      Obietnica<jakikolwiek>

  • messageSkipWaiting

    void

    Wysyła komunikat {type: 'SKIP_WAITING'} do skryptu service worker, który znajduje się obecnie w stanie waiting powiązanym z bieżącą rejestracją.

    Jeśli nie ma bieżącej rejestracji lub nie ma skryptu service worker, waiting, wywołanie tego nie przyniesie żadnego efektu.

    Funkcja messageSkipWaiting wygląda tak:

    ()=> {...}

  • register

    void

    Rejestruje skrypt service worker dla tego adresu URL skryptu instancji i opcji skryptu service worker. Domyślnie ta metoda opóźnia rejestrację do momentu załadowania okna.

    Funkcja register wygląda tak:

    (options?: object)=> {...}

    • Opcje

      obiekt opcjonalnie

      • w bezpośrednim sąsiedztwie

        wartość logiczna opcjonalna

    • returns

      Promise<ServiceWorkerRegistration>

  • aktualizować

    void

    Sprawdza dostępność aktualizacji zarejestrowanego skryptu service worker.

    Funkcja update wygląda tak:

    ()=> {...}

    • returns

      Promise<void>

WorkboxEventMap

WorkboxLifecycleEvent

Właściwości

  • isExternal

    wartość logiczna opcjonalna

  • isUpdate

    wartość logiczna opcjonalna

  • originalEvent

    Wydarzenie opcjonalnie

  • sw

    ServiceWorker opcjonalny

  • cel

    WorkboxEventTarget opcjonalnie

  • typ

    typeOperator

WorkboxLifecycleEventMap

WorkboxLifecycleWaitingEvent

Właściwości

  • isExternal

    wartość logiczna opcjonalna

  • isUpdate

    wartość logiczna opcjonalna

  • originalEvent

    Wydarzenie opcjonalnie

  • sw

    ServiceWorker opcjonalny

  • cel

    WorkboxEventTarget opcjonalnie

  • typ

    typeOperator

  • wasWaitingBeforeRegister

    wartość logiczna opcjonalna

WorkboxMessageEvent

Właściwości

  • dane

    Dowolne

  • isExternal

    wartość logiczna opcjonalna

  • originalEvent

    Zdarzenie

  • ports

    typeOperator

  • sw

    ServiceWorker opcjonalny

  • cel

    WorkboxEventTarget opcjonalnie

  • typ

Metody

messageSW()

workbox-window.messageSW(
  sw: ServiceWorker,
  data: object,
)

Wysyła obiekt danych do skryptu service worker przez postMessage i przekazuje odpowiedź (jeśli została wysłana).

Odpowiedź można ustawić w module obsługi wiadomości w skrypcie service worker, wywołując metodę event.ports[0].postMessage(...), co spowoduje zrealizowanie obietnicy zwróconej przez metodę messageSW(). Jeśli nie otrzymasz odpowiedzi, obietnica nie zostanie rozwiązana.

Parametry

  • sw

    ServiceWorker

    Skrypt service worker, do którego ma zostać wysłana wiadomość.

  • dane

    obiekt

    Obiekt do wysłania do skryptu service worker.

Akcje powrotne

  • Obietnica<jakikolwiek>