Qu'est-ce qu'un Service Worker ? Cycle de vie, cache et limites
Un service worker est un script entre la page web et le réseau. Cycle de vie, schémas de cache, limites et erreurs fréquentes expliqués.
Qu'est-ce qu'un service worker ?
Un service worker est un fichier JavaScript que le navigateur exécute en arrière-plan, séparément de la page, et qui peut intercepter les requêtes réseau des pages de son périmètre. MDN le décrit comme un serveur proxy placé entre l'application web, le navigateur et le réseau. Comme il peut répondre aux requêtes depuis un cache, il rend possibles l'usage hors ligne et les rechargements quasi instantanés. C'est la base des applications web progressives.
Comment ça fonctionne
La page enregistre le worker avec navigator.serviceWorker.register('/sw.js'). Il suit ensuite un cycle de vie :
- Install. Déclenché quand le navigateur trouve un nouveau fichier de worker. Le worker y crée généralement un cache et y range les ressources dont l'application a besoin hors ligne.
- Waiting. Si un ancien worker contrôle encore des pages ouvertes, le nouveau attend. Il ne s'active que lorsqu'aucune page n'utilise l'ancienne version, sauf s'il appelle
skipWaiting(). - Activate. Un bon moment pour supprimer les anciens caches. Un worker installé pour la première fois ne contrôle les pages déjà ouvertes qu'après rechargement, sauf s'il appelle
clients.claim(). - Fetch et autres événements. Le worker traite les événements
fetchet décide de la réponse avecrespondWith(). Il peut aussi recevoir des messages push et des événements de synchronisation en arrière-plan. - Update. Le navigateur retélécharge le fichier du worker lors d'une navigation vers une page du périmètre, et aussi quand un événement se déclenche alors que le fichier n'a pas été vérifié depuis 24 heures. Un fichier modifié s'installe comme une nouvelle version.
Deux contraintes comptent en pratique. Un service worker ne fonctionne que dans un contexte sécurisé, c'est-à-dire en HTTPS (localhost est considéré comme sûr pour le développement). Et il s'exécute dans un contexte de worker : pas d'accès au DOM, pas de XHR synchrone ni de Web Storage. Les pages lui parlent via postMessage(). Le navigateur peut arrêter un worker inactif, c'est pourquoi le travail qui doit aboutir est enveloppé dans event.waitUntil().
Schémas de cache courants
- Cache d'abord, réseau en secours. Renvoie la copie en cache si elle existe, sinon va la chercher. Convient aux CSS, JS et polices dont le nom porte une empreinte.
- Réseau d'abord, cache en secours. Essaie le réseau et sert le cache hors ligne. Convient au HTML qui doit rester à jour.
- Stale while revalidate. Répond tout de suite depuis le cache et rafraîchit le cache en arrière-plan. Convient au contenu qui peut être légèrement périmé.
- Page de secours hors ligne. Si la requête n'est pas en cache et que le réseau échoue, renvoie une page hors ligne préparée plutôt qu'une erreur.
- Navigation preload. Lance la requête réseau en parallèle du démarrage du worker pour qu'il n'ajoute pas de latence aux navigations.
Exemple
Un site d'actualités met en cache à l'avance son app shell (squelette HTML, CSS, JS) dans l'événement install. À chaque requête, le worker sert les ressources statiques en cache d'abord et les pages d'articles en réseau d'abord, avec la dernière copie en cache hors ligne. Quand l'équipe publie un nouveau sw.js avec un cache nommé v2, le gestionnaire activate supprime le cache v1.
Erreurs courantes
- Servir le HTML cache d'abord, sans issue de secours. Les utilisateurs voient l'ancienne page jusqu'à la mise à jour du worker. Utilisez réseau d'abord pour les documents et versionnez vos caches.
- Oublier
waitUntil(). Le worker peut être arrêté avant la fin de l'écriture dans le cache. - Ne pas cloner les réponses. Le corps d'une réponse ne se lit qu'une fois : clonez-la avant de la stocker et de la renvoyer.
- Employer
skipWaiting()à la légère. Un nouveau worker peut prendre la main sur une page chargée avec les anciennes ressources. - Mettre en cache sans précaution des réponses d'API ou des pages authentifiées. Le cache d'un worker ne suit pas de lui-même les règles de fraîcheur HTTP ; c'est vous qui fixez l'expiration. Le côté en-têtes est traité dans cache d'API.
- Négliger la première visite. L'enregistrement et l'installation coûtent de la bande passante et du processeur avant tout bénéfice sur les visites suivantes.
Service workers, couches de cache et performance
Un service worker n'est qu'une couche parmi d'autres. Le cache HTTP du navigateur suit les en-têtes Cache-Control, un CDN sert des copies partagées depuis la périphérie, et le stockage de la Cache API du worker est piloté par votre propre code. Un web worker est autre chose : il sort le calcul du thread principal mais n'intercepte pas les requêtes. Dans une application monopage, un worker qui met en cache l'app shell peut accélérer les rechargements. L'effet n'apparaît dans les Core Web Vitals que lorsque les pages sont servies depuis le cache : mesurez-le plutôt que de le supposer, en comparant les visites répétées grâce à la surveillance des utilisateurs réels et en suivant les scores de laboratoire dans le temps avec des audits Lighthouse planifiés. Les caches modifient aussi ce que mesure un test de performance, comme le montrent nos guides sur les tests de charge des applications web progressives et l'invalidation du cache dans les tests de performance. Pour l'API complète, consultez la référence de la Service Worker API sur MDN.
Questions fréquentes : Service Workers
Ai-je besoin d'un service worker ?
Seulement si vous voulez un mode hors ligne, des notifications push ou un contrôle programmatique du cache. Un site qui charge déjà vite et qui a peu de visiteurs récurrents gagnera souvent peu au regard de la complexité ajoutée.
Quelle est la différence entre un service worker et un web worker ?
Un web worker exécute des scripts dans un thread secondaire pour que les calculs lourds ne bloquent pas la page. Un service worker se place entre la page et le réseau, peut répondre aux requêtes depuis un cache et survit à une simple consultation de page.
Pourquoi mon nouveau service worker ne prend-il pas effet ?
La nouvelle version s'installe mais attend qu'aucune page ouverte n'utilise l'ancienne. Fermez tous les onglets, ou appelez skipWaiting() et clients.claim() si vous acceptez les compromis.
Un service worker exige-t-il HTTPS ?
Oui. Les service workers ne sont disponibles que dans des contextes sécurisés. Les navigateurs traitent aussi http://localhost comme sûr pour que vous puissiez développer en local.
Un service worker peut-il voir ou modifier le DOM de la page ?
Non. Il n'a pas accès au DOM et s'exécute dans un autre thread. Il échange des messages avec les pages via postMessage().
Comment me débarrasser d'un service worker défectueux ?
Publiez un sw.js de remplacement qui vide ses caches dans l'événement activate, ou désinscrivez-le depuis la page. Prévoyez ce coupe-circuit avant la mise en production, car un worker qui met le HTML en cache peut continuer à servir des pages périmées.
Termes associés
- Web Workers : définition, cas d'usage, exemples
- Qu'est-ce que l'API testing ?
- Qu'est-ce que l'Application Performance Monitoring (APM) ?
- Qu’est-ce que le benchmark testing ?
- Qu'est-ce que le breakpoint testing ?
- Qu'est-ce que le mode appareil du navigateur ?
- Qu'est-ce que le capacity testing ?
- Qu'est-ce que le Cloud Monitoring ?
Outils LoadFocus connexes
Mettez ce concept en pratique avec LoadFocus, la plateforme même qui propulse tout ce que vous venez de lire.