Deweloperzy korzystający z usług działających w tle i z interfejsu 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 importowania skryptów
importScripts()
nakazuje Twojemu głównemu skryptowi service worker wstrzymanie jego 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 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 próbują ograniczyć możliwe problemy z wydajnością związane z „pobieraniem i uruchamianiem kodu synchronicznego”, automatycznie buforując wszystko pobrane przez importScripts()
. Oznacza to, że po początkowym pobieraniu wykonanie zaimportowanego kodu jest bardzo proste.
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
.
W starszych wersjach Chrome 71 asynchroniczne wywoływanie funkcji importScripts()
poza modułem obsługi 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));
});
Twój kod mechanizmu 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 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.
To logowanie jest wstępem do Chrome 72, w której zamiast ostrzeżenia w logu duplikaty adresów URL będą powodować odrzucenie cache.addAll()
. Jeśli wywołujesz funkcję cache.addAll()
w ramach łańcucha obietnic przekazanych do InstallEvent.waitUntil()
(co jest typową praktyką), odrzucenie może spowodować, że nie uda się zainstalować skryptu service worker.
Oto, w jaki sposób możesz napotkać problem:
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. '/'
i '/index.html'
) nie powoduje 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. Zdarza się jednak, że nie zauważasz takiego zachowania w innych przeglądarkach, więc chcieliśmy zwrócić uwagę na tę zmianę przed zmianą sposobu działania Chrome.