Supprimer les service workers qui présentent des bugs

Parfois, un service worker avec bug est déployé, puis il y a des problèmes. Par exemple, un service worker peut être analysé au moment de l'enregistrement et se terminer correctement. Cependant, un code comportant des bugs dans un événement fetch peut l'empêcher de répondre aux requêtes, ce qui génère une page vierge. Autre possibilité : le balisage de page est mis en cache de manière agressive, De plus, un service worker ne renvoie des réponses de balisage obsolètes qu'à partir d'une instance Cache pour les visites ultérieures.

Un service worker peut effectuer de nombreuses actions rétroactives, et c'est un problème effrayant sur un site Web de production. Malgré cela, tout n'est pas perdu. Il existe des moyens de remédier à la situation et de vous remettre sur les rails.

Déployer un service worker no-op

Lorsqu'un service worker fonctionne avec des bugs, il suffit généralement de déployer un service de base Service worker no-op qui s'installe et s'active immédiatement sans gestionnaire d'événements fetch:

// sw.js

self.addEventListener('install', () => {
  // Skip over the "waiting" lifecycle state, to ensure that our
  // new service worker is activated immediately, even if there's
  // another tab open controlled by our older service worker code.
  self.skipWaiting();
});

self.addEventListener('activate', () => {
  // Optional: Get a list of all the current open windows/tabs under
  // our service worker's control, and force them to reload.
  // This can "unbreak" any open windows/tabs as soon as the new
  // service worker activates, rather than users having to manually reload.
  self.clients.matchAll({
    type: 'window'
  }).then(windowClients => {
    windowClients.forEach((windowClient) => {
      windowClient.navigate(windowClient.url);
    });
  });
});

Ce service worker s'installe et s'active immédiatement en appelant self.skipWaiting() dans l'événement install. Vous pouvez éventuellement déployer du code supplémentaire dans l'événement activate pour forcer l'actualisation de tous les autres onglets ouverts avec un WindowClient contrôlé par le service worker.

Il est très important qu'un service worker no-op ne contienne aucun gestionnaire d'événements fetch. Lorsqu'un service worker ne traite pas les requêtes, ces requêtes sont transmises au navigateur comme si aucun service worker n'était présent. Une fois qu'un service worker no-op est déployé, il peut être corrigé et déployé ultérieurement en tant que mise à jour.

Cette approche fonctionne en partie parce que les navigateurs proposent des protections renforcées contre le placement de service workers dans le cache HTTP et qu'ils effectuent des vérifications octet par octet du contenu d'un service worker pour détecter les mises à jour. Ces valeurs par défaut permettent de déployer un remplacement no-op pour un service worker comportant des bugs afin de résoudre le problème rapidement.

Mesures supplémentaires à prendre

Le déploiement d'un service worker no-op devrait suffire à neutraliser un bug. mais des mesures supplémentaires peuvent être prises si nécessaire.

Que faire si vous ne connaissez pas l'URL de l'ancien service worker ?

Parfois, l'URL d'un service worker précédemment installé est inconnue. Cela peut être dû au fait qu'il possède plusieurs versions (par exemple, le nom du fichier contient un hachage). Dans ce cas, il peut être difficile de déployer un service worker no-op correspondant à l'URL de chaque ancien service worker enregistré. Cela va à l'encontre des bonnes pratiques, car les développeurs ne se souviendront probablement pas de chaque hachage pour chaque version de service worker déployée.

Heureusement, un en-tête de requête HTTP utile est envoyé avec une requête pour un script de service worker: Service-Worker Sur le serveur Web, vérifiez la présence de cet en-tête et interceptez la requête de diffusion à un service worker no-op. La réalisation de cet exploit dépend du serveur Web et de la pile backend utilisés. Nous vous invitons donc à consulter la documentation du langage concerné pour savoir comment procéder.

Pour les futurs déploiements de service workers, conservez des noms d'éléments sans gestion des versions (par exemple, sw.js). Cela rendra les choses beaucoup moins compliquées par la suite.

Définir un en-tête Clear-Site-Data

Certains navigateurs annulent l'enregistrement de tous les service workers pour une origine si une L'en-tête de réponse Clear-Site-Data avec la valeur 'storage' est défini. Il y a toutefois quelques points à garder à l'esprit concernant cette approche:

La prise en charge de cet en-tête n'étant pas totale, il ne peut pas être utilisé seul pour résoudre le problème. Il est donc préférable de considérer Clear-Site-Data comme une mesure à prendre en plus du déploiement d'un service worker no-op.

Les dommages ne sont pas permanents

Cela peut faire peur lorsque l'expérience utilisateur est perturbée par un service worker, en particulier pour les sites Web volumineux et bien connus, mais les dommages sont temporaires et réversibles.

S'il est nécessaire de déployer un service worker no-op pour régler la situation, prendre le temps après coup pour comprendre exactement ce qui s'est mal passé. À l'avenir, assurez-vous qu'un service worker ne traite que les requêtes attendues. Effectuez des tests fréquents en préproduction et déployez les mises à jour uniquement lorsque vous êtes sûr de la fiabilité.