Gérer les requêtes de navigation

Répondre 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 effectué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 ouvre une nouvelle URL. C'est là que les service workers ont le plus d'impact sur les performances: si vous les utilisez pour répondre aux requêtes de navigation sans attendre la connexion du réseau, vous pouvez vous assurer que les navigations sont rapides et fiables, en plus d'être résilientes en cas d'indisponibilité du réseau. Il s'agit du seul gain de performances sans frais par un service worker par rapport à ce qu'il est possible de faire avec la mise en cache HTTP.

Comme détaillé dans le guide Identifier les ressources chargées à partir du réseau, une requête de navigation est la première des nombreuses requêtes effectuées dans la "cascade" du trafic réseau. Le code HTML que vous chargez via une requête de navigation déclenche le flux de toutes les autres requêtes concernant les 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 requête de navigation en vérifiant la propriété request.mode sur 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 un élément 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, afin de s'assurer que le code HTML, ainsi que la chaîne de requêtes réseau ultérieures, sont (raisonnablement) à jour. Malheureusement, le fait d'aller à l'encontre du réseau chaque fois que l'utilisateur accède à une nouvelle page signifie que chaque navigation peut être lente. Au minimum, cela signifie qu'il ne sera pas fiable rapidement.

Différentes approches pour les architectures

Il peut être difficile de savoir comment répondre aux requêtes de navigation tout en évitant le réseau. 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éterminer quelle approche est la plus viable.

Petits sites statiques

Si votre application Web comporte un nombre relativement petit (par exemple, une dizaine) 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 code HTML mis en cache approprié.

Grâce à la mise en cache préalable, 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 recréez votre site et que vous redéployez votre service worker.

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

Applications monopages

Une architecture monopage est souvent utilisée par les applications Web modernes. Ici, 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 constitue en fait une navigation "simulée". Bien que les navigations suivantes puissent être "faux", la navigation initiale est réelle. Il est donc important de vous 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 de l'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é mis en pré-cache, quelle que soit l'URL demandée. Ce code HTML doit être simple, et comporter éventuellement un indicateur de chargement générique ou 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 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 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 figurant dans la section Autres messages vous concernent probablement.

Toutefois, pour un certain sous-ensemble d'applications multipages, vous pouvez peut-être implémenter un service worker qui réplique entièrement la logique utilisée sur votre serveur Web pour générer du code HTML. Cette méthode 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, 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 appartient à cette catégorie et que vous souhaitez découvrir une approche pour transférer la génération HTML du réseau vers votre service worker, consultez les conseils de la section Au-delà des applications monopages : architectures alternatives pour votre PWA pour vous aider à démarrer.

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 traiter d'autres requêtes non HTML) ne ralentit pas vos navigations. Le démarrage du service worker sans l'utiliser pour répondre à une requête de navigation entraîne un faible niveau de latence (comme expliqué sur la page Créer des applications plus rapides et plus résilientes avec Service Worker). Vous pouvez limiter 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 le préchargement de la navigation est compatible et, le cas échéant, simplifie le processus permettant de demander à votre service worker d'utiliser la réponse réseau.

Photo par Aaron Burden sur Unsplash