Gérer les requêtes de navigation

Répondez aux requêtes de navigation sans attendre sur le réseau à l'aide d'un service worker.

Les requêtes de navigation sont des requêtes de documents HTML envoyées par votre navigateur chaque fois que vous saisissez une nouvelle URL dans la barre de navigation ou que vous suivez un lien sur une page qui vous redirige vers une nouvelle URL. C'est là que les service workers ont le plus d'impact sur les performances: si vous utilisez un service worker pour répondre aux requêtes de navigation sans attendre le réseau, vous pouvez vous assurer que les navigations sont rapides et fiables, en plus d'être résilientes lorsque le réseau n'est pas disponible. Il s'agit du plus grand gain de performances qu'un service worker peut apporter par rapport à ce qui est possible avec le stockage en cache HTTP.

Comme indiqué dans le guide Identifier les ressources chargées à partir du réseau, une requête de navigation est la première d'un grand nombre de requêtes effectuées dans la cascade du trafic réseau. Le code HTML que vous chargez via une requête de navigation lance le flux de toutes les autres requêtes de sous-ressources telles que les images, les scripts et les styles.

Dans le gestionnaire d'événements fetch d'un service worker, vous pouvez déterminer si une requête est une navigation en vérifiant la propriété request.mode sur le FetchEvent. Si elle est définie sur 'navigate', il s'agit d'une requête de navigation.

En règle générale, n'utilisez pas de Cache-Control headers de longue durée pour mettre en cache la réponse HTML d'une requête de navigation. Elles doivent normalement être satisfaites via le réseau, avec Cache-Control: no-cache, pour s'assurer que le code HTML, ainsi que la chaîne de requêtes réseau ultérieures, est (raisonnablement) à jour. S'opposer au réseau chaque fois que l'utilisateur accède à une nouvelle page signifie malheureusement que chaque navigation peut être lente. Au moins, cela signifie qu'il ne sera pas fiable.

Différentes approches pour les architectures

Il peut être difficile de déterminer comment répondre aux requêtes de navigation tout en évitant le réseau. L'approche appropriée dépend fortement de l'architecture de votre site Web et du nombre d'URL uniques vers lesquelles les utilisateurs peuvent accéder.

Bien qu'il n'existe pas de solution universelle, les consignes générales suivantes devraient vous aider à choisir l'approche la plus viable.

Petits sites statiques

Si votre application Web se compose d'un nombre relativement faible (une vingtaine) d'URL uniques, et que chacune de ces URL correspond à un fichier HTML statique différent, une approche viable consiste simplement à mettre en cache tous ces fichiers HTML et à répondre aux requêtes de navigation avec le fichier HTML mis en cache approprié.

Grâce au préchargement, vous pouvez mettre en cache le code HTML à l'avance, dès que le service worker est installé, et mettre à jour le code HTML mis en cache chaque fois que vous reconstruisez votre site et redéployez votre service worker.

Si vous préférez éviter de précacher l'intégralité de votre code HTML (par exemple, parce que les utilisateurs ne naviguent que sur un sous-ensemble d'URL de votre site), vous pouvez utiliser une stratégie de mise en cache d'exécution obsolète pendant la validation. Faites toutefois attention à cette approche, car chaque document HTML est mis en cache et mis à jour séparément. L'utilisation de la mise en cache d'exécution pour le code HTML est la plus appropriée si vous disposez d'un petit nombre d'URL consultées fréquemment par le même ensemble d'utilisateurs et si vous êtes à l'aise avec la révalidation de ces URL indépendamment les unes des autres.

Applications monopages

Les applications Web modernes utilisent fréquemment une architecture à page unique. Dans ce cas, le code JavaScript côté client modifie le code HTML en réponse aux actions de l'utilisateur. Ce modèle utilise l'API History pour modifier l'URL actuelle lorsque l'utilisateur interagit avec l'application Web, ce qui équivaut à une navigation "simulée". Bien que les navigations ultérieures puissent être "factices", la navigation initiale est réelle. Il est donc important de s'assurer qu'elle n'est pas bloquée sur le réseau.

Heureusement, si vous utilisez l'architecture monopage, il existe un modèle simple à suivre pour diffuser la navigation initiale à partir du cache: le shell d'application. Dans ce modèle, votre service worker répond aux requêtes de navigation en renvoyant le même fichier HTML qui a déjà été préchargé, quelle que soit l'URL demandée. Ce code HTML doit être basique, composé par exemple d'un indicateur de chargement générique ou d'un squelette de contenu. Une fois que le navigateur a chargé ce code HTML à partir du cache, votre code JavaScript côté client existant prend le relais et affiche le contenu HTML correct pour l'URL à partir de la requête de navigation d'origine.

Workbox fournit les outils dont vous avez besoin pour implémenter cette approche. navigateFallback option vous permet de spécifier le document HTML à utiliser comme shell d'application, ainsi qu'une liste d'autorisation et de refus facultative pour limiter ce comportement à un sous-ensemble de vos URL.

Applications multipages

Si votre serveur Web génère le code HTML de votre site de manière dynamique ou si vous avez plus d'une dizaine de pages uniques, il est beaucoup plus difficile d'éviter le réseau lors du traitement des requêtes de navigation. Les conseils de la section Tout le reste vous seront probablement utiles.

Toutefois, pour un certain sous-ensemble d'applications multipages, vous pouvez implémenter un service worker qui reproduit entièrement la logique utilisée dans votre serveur Web pour générer du code HTML. Cette approche fonctionne mieux si vous pouvez partager des informations de routage et de création de modèles entre les environnements de serveur et de service worker, et en particulier si votre serveur Web utilise JavaScript (sans s'appuyer sur des fonctionnalités spécifiques à Node.js, comme l'accès au système de fichiers).

Si votre serveur Web appartient à cette catégorie et que vous souhaitez explorer une approche pour déplacer la génération HTML hors du réseau et dans votre service worker, les conseils de Au-delà des SPA : architectures alternatives pour votre PWA peuvent vous aider à vous lancer.

Tout le reste

Si vous ne pouvez pas répondre aux requêtes de navigation avec du code HTML mis en cache, vous devez prendre des mesures pour vous assurer que l'ajout d'un service worker à votre site (pour gérer d'autres requêtes non HTML) ne ralentit pas vos navigations. Démarrer le service worker sans l'utiliser pour répondre à une requête de navigation introduit une petite latence (comme expliqué dans Créer des applications plus rapides et plus résilientes avec un service worker). Vous pouvez atténuer ce surcoût en activant une fonctionnalité appelée préchargement de la navigation, puis en utilisant la réponse réseau préchargée dans votre gestionnaire d'événements fetch.

Workbox fournit une bibliothèque d'assistance qui détecte si le préchargement de navigation est compatible et, le cas échéant, simplifie le processus d'incitation de votre service worker à utiliser la réponse réseau.

Photo par Aaron Burden, publiée sur Unsplash