Poprawiono funkcje cache.addAll() i importScripts() w Chrome 71.

Deweloperzy używający skryptów service worker i Cache Storage API powinni szukać 2 niewielkich zmian wprowadzonych w Chrome 71. Obie zmiany sprawią, że implementacja Chrome będzie bardziej zgodna ze specyfikacjami i innymi przeglądarkami.

Nie zezwalaj na asynchroniczne importScripts()

importScripts() prosi główny skrypt service worker o wstrzymanie bieżącego wykonania, pobranie dodatkowego kodu z danego adresu URL i uruchomienie go do końca w bieżącym zakresie globalnym. Gdy to zrobisz, główny skrypt service worker wznowi wykonanie. importScripts() przydaje się, gdy chcesz podzielić główny skrypt service worker na mniejsze części ze względów organizacyjnych lub pobrać kod innej firmy, aby dodać do niego nowe funkcje.

Przeglądarki starają się ograniczyć możliwe problemy z wydajnością związane z pobieraniem i uruchamianiem kodu synchronicznego, automatycznie buforując pliki pobrane przez importScripts(). Oznacza to, że po wstępnym pobraniu nie ma zbyt dużego nakładu pracy przy wykonywaniu zaimportowanego kodu.

Aby to działało, przeglądarka musi jednak wiedzieć, że po początkowej instalacji do skryptu service worker nie jest importowany żaden „niespodziewany kod”. Zgodnie ze specyfikacją skryptu service worker wywołanie importScripts() powinno działać tylko podczas synchronicznego wykonywania skryptu skryptu service worker najwyższego poziomu lub – w razie potrzeby – asynchronicznie wewnątrz modułu obsługi install.

W wersjach sprzed Chrome 71 asynchroniczne wywoływanie funkcji importScripts() poza modułem install działało. Począwszy od Chrome 71 wywołania te wywołują wyjątek w czasie działania (chyba że ten sam adres URL został wcześniej zaimportowany do modułu obsługi install), co odpowiada działaniu w innych przeglądarkach.

Zamiast kodu w ten sposób:

// This only works in Chrome 70 and below.
self.addEventListener('fetch', event => {
  importScripts('my-fetch-logic.js');
  event.respondWith(self.customFetchLogic(event));
});

Twój kod skryptu service worker powinien wyglądać tak:

// Move the importScripts() to the top-level scope.
// (Alternatively, import the same URL in the install handler.)
importScripts('my-fetch-logic.js');
self.addEventListener('fetch', event => {
  event.respondWith(self.customFetchLogic(event));
});

Wycofanie powtarzających się adresów URL przekazywanych do cache.addAll()

Jeśli korzystasz z interfejsu Cache Storage API razem z skryptem service worker, wprowadziliśmy w Chrome 71 kolejną niewielką zmianę, która jest zgodna z odpowiednią specyfikacją. Jeśli ten sam adres URL jest przekazywany wiele razy w jednym wywołaniu funkcji cache.addAll(), specyfikacja informuje, że obietnica zwrócona przez wywołanie powinna zostać odrzucona.

W wersjach Chrome wcześniejszych niż 71 takie działanie nie było wykrywane, a duplikaty adresów URL były w praktyce ignorowane.

Zrzut ekranu z komunikatem ostrzegawczym w konsoli Chrome
Od wersji Chrome 71 w konsoli będzie pojawiać się komunikat ostrzegawczy.

Logowanie to wprowadzenie do Chrome 72, w którym duplikaty adresów URL zamiast zwykłego ostrzeżenia spowodują odrzucenie cache.addAll(). Jeśli wywołujesz cache.addAll() w ramach łańcucha obietnic przekazanego do InstallEvent.waitUntil(), zgodnie z częstą praktyką odrzucenie może spowodować, że skrypt service worker się nie zainstaluje.

Oto możliwe przyczyny problemów:

const urlsToCache = [
  '/index.html',
  '/main.css',
  '/app.js',
  '/index.html', // Oops! This is listed twice and should be removed.
];

self.addEventListener('install', event => {
  event.waitUntil(
    caches.open('my-cache').then(cache => cache.addAll(urlsToCache))
  );
});

To ograniczenie dotyczy tylko rzeczywistych adresów URL przekazywanych do cache.addAll(). Zapisywanie w pamięci podręcznej 2 równoważnych odpowiedzi z różnymi adresami URL, np. '/' i '/index.html', nie spowoduje odrzucenia.

Przetestuj implementację mechanizmu Service Worker w szerokim zakresie

Skrypty service worker są obecnie powszechnie stosowane we wszystkich popularnych przeglądarkach typu „zawsze aktualne”. Jeśli regularnie testujesz progresywną aplikację internetową w różnych przeglądarkach lub masz dużą liczbę użytkowników, którzy nie używają Chrome, prawdopodobnie niespójności zostały już przez Ciebie wykryte i zaktualizowany kod. Jednak szkoda, że nie zauważyliście tego zjawiska w innych przeglądarkach, chcemy zwrócić uwagę na tę zmianę, zanim zmienimy sposób działania Chrome.