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

Les développeurs qui utilisent des service workers et l'API Cache Storage doivent guetter le déploiement de deux petites modifications dans Chrome 71. Ces deux modifications permettent d'aligner davantage l'implémentation de Chrome avec les spécifications et les autres navigateurs.

Désactivation de la fonction importScripts() asynchrone.

importScripts() indique à votre script de service worker principal d'interrompre son exécution en cours, de télécharger du code supplémentaire à partir d'une URL donnée et de l'exécuter intégralement dans le champ d'application global actuel. Une fois cette opération terminée, le script principal du service worker reprend l'exécution. importScripts() s'avère pratique lorsque vous souhaitez diviser votre script principal de service worker en éléments plus petits pour des raisons organisationnelles, ou extraire 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 tous les éléments extraits via importScripts(). Cela signifie qu'après le téléchargement initial, l'exécution du code importé entraîne très peu de frais.

Pour que cela fonctionne, le navigateur doit toutefois savoir qu'aucun code "surprise" ne sera importé dans le service worker après l'installation initiale. Conformément à la spécification du service worker, l'appel de importScripts() est censé ne 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, il était possible d'appeler importScripts() de manière asynchrone en dehors du gestionnaire install. À 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), ce qui correspond au comportement dans les 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));
});

Le code de votre 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 en même temps qu'un service worker, une autre modification mineure est apportée à Chrome 71 afin de s'aligner sur les spécifications pertinentes. Lorsque la même URL est transmise plusieurs fois à un seul appel à cache.addAll(), la spécification indique que la promesse renvoyée par l'appel doit être rejetée.

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

Capture d'écran du message d'avertissement dans la console Chrome
À partir de Chrome 71, un message d'avertissement s'affichera 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 un refus de cache.addAll(). Si vous appelez cache.addAll() dans le cadre d'une chaîne de promesse transmise à InstallEvent.waitUntil(), comme c'est la pratique courante, ce refus peut entraîner l'échec de l'installation de votre service worker.

Voici comment vous pourriez 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 deux réponses équivalentes avec des URL différentes, telles que '/' et '/index.html', ne déclenchera pas de refus.

Testez largement l'implémentation de votre service worker

À ce stade, les service workers sont largement mis en œuvre sur tous les principaux navigateurs"intemporels". Si vous testez régulièrement votre progressive web app sur plusieurs navigateurs ou si vous avez un grand nombre d'utilisateurs qui n'utilisent pas Chrome, il est probable que vous ayez déjà détecté l'incohérence et que vous ayez mis à jour votre code. Toutefois, si vous n'avez pas remarqué ce comportement dans d'autres navigateurs, nous souhaitons vous informer de ce changement avant de modifier le comportement de Chrome.