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

Deweloperzy korzystający z usług w tleinterfejsu Cache Storage API powinni zwrócić uwagę na 2 mniejsze zmiany wprowadzone w Chrome 71. Obie zmiany powodują, że implementacja w Chrome jest bardziej zgodna z specyfikacją i innymi przeglądarkami.

Zabranie dostępu do asynchronicznego importScripts()

importScripts() mówi głównemu skryptowi workera usługi, aby wstrzymał bieżące wykonywanie, pobrał dodatkowy kod z danego adresu URL i uruchomił go do końca w bieżącym zakresie globalnym. Gdy to zrobisz, skrypt głównego service workera wznowi działanie. importScripts() przydaje się, gdy chcesz podzielić główny skrypt service workera na mniejsze części ze względów organizacyjnych lub w celu zaimportowania kodu zewnętrznego, aby dodać nowe funkcje do service workera.

Przeglądarki starają się ograniczyć możliwe problemy z wydajnością związane z „pobieraniem i uruchamianiem kodu synchronicznego” przez automatyczne buforowanie wszystkich danych pobieranych za pomocą importScripts(). Oznacza to, że po początkowym pobraniu nie ma prawie żadnego obciążenia związanego z wykonywaniem zaimportowanego kodu.

Aby to działało, przeglądarka musi wiedzieć, że po początkowej instalacji nie będzie importowany do workera usługi żaden „niespodziewany” kod. Zgodnie ze specyfikacją usługi workera wywołanie importScripts() powinno działać tylko podczas synchronicznego wykonywania skryptu usługi workera na najwyższym poziomie lub, w razie potrzeby, asynchronicznie wewnątrz obsługi install.

Przed wersją 71 Chrome wywołanie funkcji importScripts() w sposób asynchroniczny poza obciążeniem install działało. Począwszy od Chrome 71 te wywołania rzucają wyjątkiem czasu wykonywania (chyba że ten sam adres URL został wcześniej zaimportowany w obiekcie install), co odpowiada działaniu w innych przeglądarkach.

Zamiast kodu takiego jak ten:

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

Kod usługi 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 metody cache.addAll();

Jeśli używasz interfejsu Cache Storage API razem z usługą wtyczki, w Chrome 71 wprowadzono kolejną niewielką zmianę, aby dostosować go do odpowiedniej specyfikacji. Jeśli ten sam adres URL jest przekazywany wielokrotnie do pojedynczego wywołania funkcji cache.addAll(), specyfikacja mówi, że obietnica zwrócona przez wywołanie powinna zostać odrzucona.

W wersji Chrome 71 i starszych nie wykryto tego problemu, a zduplikowane adresy URL były ignorowane.

Zrzut ekranu pokazujący komunikat ostrzeżenia w konsoli Chrome
Począwszy od wersji 71 Chrome zobaczysz w konsoli ostrzeżenie.

To logowanie jest wstępem do Chrome 72, w której zamiast ostrzeżenia w logach duplikaty adresów URL będą powodować odrzucenie cache.addAll(). Jeśli wywołujesz cache.addAll() w ramach łańcucha obietnic przekazywanych do InstallEvent.waitUntil(), odrzucenie może spowodować niepowodzenie instalacji skryptu service worker.

Oto, co może pójść nie tak:

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 funkcji cache.addAll(). Zapisywanie w pamięci podręcznej dwóch równoważnych odpowiedzi z różnymi adresami URL (np. '/''/index.html') nie spowoduje odrzucenia.

Testowanie implementacji usługi workera na dużą skalę

W tej chwili serwisy robocze są szeroko wdrażane we wszystkich głównych przeglądarkach typu „evergreen”. Jeśli regularnie testujesz swoją progresywną aplikację internetową w różnych przeglądarkach lub masz wielu użytkowników, którzy nie korzystają z Chrome, prawdopodobnie już wykryłeś niespójność i zaktualizowałeś kod. Jednak na wypadek, gdybyś nie zauważył tego zachowania w innych przeglądarkach, chcemy poinformować Cię o zmianie, zanim wprowadzimy ją w Chrome.