Modifications apportées à cache.addAll() et importScripts() à venir dans Chrome 71

Les développeurs qui utilisent des service workers et l'API Cache Storage sont à l'affût de deux petites modifications déployées dans Chrome 71. Ces deux modifications rapprochent l'implémentation de Chrome des spécifications et des autres navigateurs.

Interdire les importScripts() asynchrones

importScripts() indique au script de service worker principal de suspendre son exécution actuelle, de télécharger du code supplémentaire à partir d'une URL donnée et de l'exécuter jusqu'à la fin dans le champ d'application global actuel. Une fois cela fait, le script du service worker principal reprend son exécution. importScripts() est utile lorsque vous souhaitez diviser votre script de service worker principal en plusieurs parties pour des raisons d'organisation ou importer du code tiers pour ajouter des fonctionnalités à votre service worker.

Les navigateurs tentent d'atténuer les problèmes de performances potentiels liés au téléchargement et à l'exécution de code synchrone en mettant automatiquement en cache tout élément extrait via importScripts(). Cela signifie qu'après le téléchargement initial, l'exécution du code importé est très peu coûteuse.

Pour que cela fonctionne, le navigateur doit savoir qu'aucun code "surprise" ne sera importé dans le service worker après l'installation initiale. Conformément à la spécification de service worker, l'appel de importScripts() ne doit fonctionner que lors de l'exécution synchrone du script de service worker de premier niveau ou, si nécessaire, de manière asynchrone dans le gestionnaire install.

Avant Chrome 71, l'appel de importScripts() de manière asynchrone en dehors du gestionnaire install fonctionnait. À partir de Chrome 71, ces appels génèrent une exception d'exécution (sauf si la même URL a déjà été importée dans un gestionnaire install), correspondant au comportement des autres navigateurs.

Au lieu d'un code comme celui-ci:

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

Votre code de service worker doit se présenter comme suit :

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

Abandon des URL répétées transmises à cache.addAll()

Si vous utilisez l'API Cache Storage avec un service worker, une autre légère modification doit être apportée à Chrome 71 pour vous aligner sur la spécification appropriée. Lorsque la même URL est transmise plusieurs fois à un seul appel de cache.addAll(), la spécification indique que la promesse renvoyée par l'appel doit être rejetée.

Avant Chrome 71, cela n'était pas détecté, et les URL en double étaient effectivement ignorées.

Capture d'écran du message d'avertissement dans la console de Chrome
À partir de Chrome 71, un message d'avertissement sera enregistré dans la console.

Cette journalisation est un prélude à Chrome 72, où au lieu d'un simple avertissement consigné, les URL en double entraîneront le refus de cache.addAll(). Si vous appelez cache.addAll() dans le cadre d'une chaîne de promesses transmise à InstallEvent.waitUntil(), comme c'est l'usage, ce refus peut entraîner l'échec de l'installation de votre service worker.

Voici comment vous pouvez rencontrer des problèmes:

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

Cette restriction ne s'applique qu'aux URL réelles transmises à cache.addAll(). La mise en cache de ce qui s'avère être deux réponses équivalentes ayant des URL différentes (comme '/' et '/index.html') ne déclenchera pas de refus.

Tester largement l'implémentation de votre service worker

À ce stade, les services workers sont largement implémentés dans tous les principaux navigateurs "evergreen". Si vous testez régulièrement votre progressive web app sur plusieurs navigateurs ou si un grand nombre d'utilisateurs n'utilisent pas Chrome, il est probable que vous ayez déjà détecté cette incohérence et mis à jour votre code. Toutefois, au cas où vous n'auriez pas remarqué ce comportement dans d'autres navigateurs, nous souhaitions vous en informer avant de modifier le comportement de Chrome.