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 pour des documents HTML effectuées par votre navigateur chaque fois que vous saisissez une nouvelle URL dans la barre de navigation ou 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 résilientes en cas d'indisponibilité du réseau. Il s'agit de la plus grande victoire en termes de performances provenant d'un service worker, par rapport à ce qui est possible avec la mise 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 parmi celles potentiellement nombreuses 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 pour des sous-ressources telles que des images, des scripts et des 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 dans le FetchEvent. S'il est défini sur 'navigate', il s'agit d'une requête de navigation.

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

Différentes approches des architectures

Savoir comment répondre aux requêtes de navigation tout en évitant le réseau peut s'avérer délicat. La bonne approche dépend en grande partie de l'architecture de votre site Web et du nombre d'URL uniques auxquelles les utilisateurs peuvent accéder.

Bien qu'il n'existe pas de solution unique, les consignes générales suivantes devraient vous aider à décider quelle approche est la plus viable.

Petits sites statiques

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

La pré-mise en cache vous permet de mettre en cache le code HTML à l'avance, dès que le service worker est installé, et de mettre à jour le code HTML mis en cache chaque fois que vous recompilez votre site et redéployez votre service worker.

Si vous préférez éviter de mettre en cache tout votre code HTML (par exemple, parce que les utilisateurs ont tendance à n'accéder qu'à un sous-ensemble d'URL sur votre site), vous pouvez utiliser une stratégie de mise en cache au moment de l'exécution stale-while-revalidate. Soyez toutefois prudent avec cette approche, car chaque document HTML est mis en cache et mis à jour séparément. L'utilisation de la mise en cache au moment de l'exécution pour HTML est plus appropriée si un petit nombre d'URL sont revisitées souvent par le même ensemble d'utilisateurs et si vous êtes d'accord pour que ces URL soient revalidées indépendamment les unes des autres.

Applications monopages

Une architecture à page unique est fréquemment utilisée par les applications Web modernes. Dans celui-ci, 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 correspond en fait à une navigation "simulée". Bien que les navigations ultérieures puissent être "fictives", la navigation initiale est réelle et il est toujours 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: l'interface système d'application. Dans ce modèle, votre service worker répond aux requêtes de navigation en renvoyant le même fichier HTML unique qui a déjà été mis en pré-cache, quelle que soit l'URL demandée. Ce code HTML doit être simple, et inclure éventuellement un indicateur de chargement générique ou un contenu squelette. 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 facultative d'autorisation et de refus 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 disposez de plus de quelques dizaines 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 Autres messages s'appliqueront probablement à vous.

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

Si votre serveur Web entre dans cette catégorie et que vous souhaitez explorer une approche permettant de transférer la génération HTML en dehors du réseau vers votre service worker, suivez les conseils de la section Au-delà des applications monopages : architectures alternatives pour votre PWA.

Divers

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 la navigation. Le démarrage du service worker sans l'utiliser pour répondre à une requête de navigation engendrera une faible latence (comme expliqué dans la section Créer des applications plus rapides et plus résilientes avec Service Worker). Vous pouvez atténuer cette surcharge en activant une fonctionnalité appelée préchargement de navigation, puis en utilisant la réponse réseau qui a été préchargée dans votre gestionnaire d'événements fetch.

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

Photo par Aaron Burden, publiée sur Unsplash