Aanpassingen aan cache.addAll() en importScripts() komen in Chrome 71

Ontwikkelaars die serviceworkers en de Cache Storage API gebruiken, moeten uitkijken naar twee kleine veranderingen die in Chrome 71 worden uitgerold. Beide veranderingen brengen de implementatie van Chrome meer in lijn met de specificaties van andere browsers.

Asynchrone importScripts() niet toestaan

importScripts() vertelt uw hoofdservicewerkerscript om de huidige uitvoering ervan te onderbreken, aanvullende code van een bepaalde URL te downloaden en deze volledig uit te voeren in het huidige globale bereik . Zodra dat is gebeurd, wordt de uitvoering van het hoofdscript van de servicemedewerker hervat. importScripts() is handig als u uw hoofdscript voor servicemedewerkers om organisatorische redenen in kleinere stukken wilt opsplitsen, of code van derden wilt gebruiken om functionaliteit aan uw servicemedewerker toe te voegen.

Browsers proberen de mogelijke prestatieproblemen van het "downloaden en uitvoeren van wat synchrone code" te beperken door alles dat via importScripts() wordt binnengehaald automatisch in de cache op te slaan, wat betekent dat er na de eerste download heel weinig overhead is betrokken bij het uitvoeren van de geïmporteerde code.

Om dat te laten werken, moet de browser echter weten dat er na de eerste installatie geen "verrassingscode" in de servicemedewerker wordt geïmporteerd. Volgens de service worker-specificatie zou het aanroepen van importScripts() alleen moeten werken tijdens de synchrone uitvoering van het service worker-script op het hoogste niveau, of, indien nodig, asynchroon binnen de install .

Vóór Chrome 71 werkte het asynchroon aanroepen van importScripts() buiten de install . Vanaf Chrome 71 genereren deze aanroepen een runtime-uitzondering (tenzij dezelfde URL eerder in een install is geïmporteerd), wat overeenkomt met het gedrag in andere browsers.

In plaats van code als deze:

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

Uw servicemedewerkercode moet er als volgt uitzien:

// 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));
});

Beëindiging van herhaalde URL's die zijn doorgegeven aan cache.addAll()

Als u de Cache Storage API samen met een servicemedewerker gebruikt, is er nog een kleine wijziging in Chrome 71 om aan te sluiten bij de relevante specificatie . Wanneer dezelfde URL meerdere keren wordt doorgegeven aan een enkele aanroep van cache.addAll() , zegt de specificatie dat de belofte die door de aanroep wordt geretourneerd, moet worden afgewezen.

Vóór Chrome 71 werd dit niet gedetecteerd en werden de dubbele URL's feitelijk genegeerd.

Een screenshot van het waarschuwingsbericht in de Chrome-console
Vanaf Chrome 71 zie je een waarschuwingsbericht geregistreerd in de console.

Deze registratie is een opmaat naar Chrome 72, waar dubbele URL's, in plaats van alleen maar een geregistreerde waarschuwing, ertoe zullen leiden dat cache.addAll() wordt afgewezen. Als u cache.addAll() aanroept als onderdeel van een belofteketen die wordt doorgegeven aan InstallEvent.waitUntil() , zoals gebruikelijk is, kan die afwijzing ertoe leiden dat uw servicemedewerker niet kan installeren.

Hier leest u hoe u in de problemen kunt komen:

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))
  );
});

Deze beperking is alleen van toepassing op de daadwerkelijke URL's die worden doorgegeven aan cache.addAll() , en het in de cache plaatsen van wat uiteindelijk twee gelijkwaardige antwoorden zijn die verschillende URL's hebben, zoals '/' en '/index.html' , zal geen afwijzing veroorzaken.

Test de implementatie van uw servicemedewerker op grote schaal

Servicemedewerkers worden op dit moment breed geïmplementeerd in alle grote "evergreen" browsers . Als u uw progressieve web-app regelmatig test in een aantal browsers, of als u een aanzienlijk aantal gebruikers heeft die Chrome niet gebruiken, is de kans groot dat u de inconsistentie al heeft ontdekt en uw code heeft bijgewerkt. Maar aangezien u dit gedrag in andere browsers niet heeft opgemerkt, wilden we de verandering benadrukken voordat we het gedrag van Chrome zouden veranderen.