Actualiser les résultats avec des ressources "stale-while-revalidate"

Il s'agit d'un outil supplémentaire qui vous aide à trouver le bon équilibre entre l'immédiateté et la fraîcheur lorsque vous diffusez votre application Web.

Quel produit a été expédié ?

stale-while-revalidate permet aux développeurs de trouver un juste équilibre entre l'immédiateté (chargement immédiat du contenu mis en cache) et la fraîcheur (assurant que les mises à jour du contenu mis en cache seront utilisées à l'avenir). Si vous gérez un service Web tiers ou une bibliothèque qui se met à jour régulièrement, ou si la durée de vie de vos éléments propriétaires a tendance à être courte, stale-while-revalidate peut être un ajout utile à vos règles de mise en cache existantes.

La possibilité de définir stale-while-revalidate avec max-age dans l'en-tête de réponse Cache-Control est disponible dans Chrome 75 et Firefox 68.

Les navigateurs qui ne sont pas compatibles avec stale-while-revalidate ignorent silencieusement cette valeur de configuration et utilisent max-age, comme je vais bientôt l'expliquer...

Qu'est-ce que cela signifie ?

Décomposons stale-while-revalidate en deux parties: l'idée qu'une réponse mise en cache peut être obsolète et le processus de revalidation.

Tout d'abord, comment le navigateur peut-il savoir si une réponse mise en cache est "obsolète" ? Un en-tête de réponse Cache-Control contenant stale-while-revalidate doit également contenir max-age. Le nombre de secondes spécifié via max-age est ce qui détermine l'obsolescence. Toute réponse mise en cache plus récente que max-age est considérée comme étant à jour, et les anciennes réponses mises en cache sont obsolètes.

Si la réponse mise en cache localement est toujours à jour, elle peut être utilisée telle quelle pour répondre à la requête d'un navigateur. Du point de vue de stale-while-revalidate, il n'y a rien à faire dans ce scénario.

Toutefois, si la réponse mise en cache est obsolète, une autre vérification en fonction de l'âge est effectuée : l'âge de la réponse mise en cache est-il compris dans la fenêtre de temps supplémentaire fournie par le paramètre stale-while-revalidate ?

Si l'ancienneté d'une réponse obsolète se situe dans cette fenêtre, elle sera utilisée pour répondre à la requête du navigateur. En parallèle, une requête de "revalidation" est effectuée sur le réseau de manière à ne pas retarder l'utilisation de la réponse mise en cache. La réponse renvoyée peut contenir les mêmes informations que la réponse précédemment mise en cache ou être différentes. Dans tous les cas, la réponse du réseau est stockée localement, remplace tout ce qui était mis en cache précédemment et réinitialise le minuteur d'actualisation utilisé lors de toutes les futures comparaisons de max-age.

Toutefois, si la réponse obsolète mise en cache est suffisamment ancienne pour sortir de la fenêtre de temps stale-while-revalidate, elle ne répondra pas à la requête du navigateur. Le navigateur récupère alors une réponse du réseau et l'utilise à la fois pour traiter la requête initiale et pour remplir le cache local avec une nouvelle réponse.

Exemple en ligne

Vous trouverez ci-dessous un exemple simple d'API HTTP permettant de renvoyer l'heure actuelle, et plus précisément, le nombre actuel de minutes après l'heure.

Dans ce scénario, le serveur Web utilise cet en-tête Cache-Control dans sa réponse HTTP:

Cache-Control: max-age=1, stale-while-revalidate=59

Ce paramètre signifie que si une requête pour l'heure est répétée au cours de la seconde qui suit, la valeur précédemment mise en cache sera toujours actualisée et utilisée telle quelle, sans revalidation.

Si une requête est répétée entre 1 et 60 secondes plus tard, la valeur mise en cache sera obsolète, mais sera utilisée pour traiter la requête API. En même temps, "en arrière-plan", une demande de revalidation est effectuée pour remplir le cache avec une nouvelle valeur pour une utilisation ultérieure.

Si une requête est répétée après plus de 60 secondes, la réponse obsolète n'est pas du tout utilisée. Le traitement de la requête du navigateur ainsi que la revalidation du cache dépendent de l'obtention d'une réponse du réseau.

Voici le détail de ces trois états distincts, ainsi que la fenêtre temporelle dans laquelle chacun d'eux s'applique pour notre exemple:

Schéma illustrant les informations de la section précédente.

Quels sont les cas d'utilisation courants ?

Bien que l'exemple ci-dessus concernant un service d'API "minute après l'heure" soit artificiel, il illustre le cas d'utilisation attendu, c'est-à-dire les services qui fournissent des informations devant être actualisées, mais pour lesquels un certain degré d'obsolescence est acceptable.

Il peut s'agir, par exemple, d'une API pour les conditions météorologiques actuelles ou des principaux titres de l'actualité rédigés au cours de l'heure précédente.

En règle générale, toute réponse mise à jour à un intervalle connu est susceptible d'être demandée plusieurs fois et statique dans cet intervalle. Elle est adaptée à la mise en cache à court terme via max-age. Utiliser stale-while-revalidate en plus de max-age augmente la probabilité que de futures requêtes puissent être traitées à partir du cache avec un contenu plus récent, sans bloquer la réponse du réseau.

Comment interagit-elle avec les service workers ?

Si vous avez entendu parler de stale-while-revalidate, il est probable que cela soit dans le contexte de recettes utilisées dans un service worker.

L'utilisation de "stale-while-revalidate" via un en-tête Cache-Control présente certaines similitudes avec son utilisation dans un service worker. De nombreuses considérations similaires s'appliquent aux compromis en matière d'actualisation et aux durées de vie maximales. Toutefois, vous devez prendre en compte certains éléments au moment de décider si vous devez implémenter une approche basée sur un service worker ou simplement vous fier à la configuration de l'en-tête Cache-Control.

Utilisez une approche service worker si...

  • Vous utilisez déjà un service worker dans votre application Web.
  • Vous avez besoin d'un contrôle ultraprécis sur le contenu de vos caches et souhaitez implémenter une règle d'expiration utilisée le moins récemment. Le module Expiration du cache de Workbox peut vous aider à ce sujet.
  • Vous souhaitez être averti lorsqu'une réponse obsolète change en arrière-plan lors de l'étape de revalidation. Le module Broadcast Cache Update de Workbox peut vous aider à ce sujet.
  • Vous devez respecter ce comportement stale-while-revalidate dans tous les navigateurs récents.

Utilisez une approche de contrôle du cache si...

  • Vous préférez ne pas avoir à gérer les frais généraux liés au déploiement et à la maintenance d'un service worker pour votre application Web.
  • Vous pouvez laisser la gestion automatique du cache du navigateur empêcher vos caches locaux de devenir trop volumineux.
  • Vous êtes d'accord avec une approche qui n'est actuellement pas prise en charge par tous les navigateurs modernes (à partir de juillet 2019, elle sera peut-être davantage prise en charge à l'avenir).

Si vous utilisez un service worker et que stale-while-revalidate est également activé pour certaines réponses via un en-tête Cache-Control, le service worker aura généralement une "première fissure" lors de la réponse à une requête. Si le service worker décide de ne pas répondre ou s'il envoie une requête réseau à l'aide de fetch() en cours de génération, le comportement configuré via l'en-tête Cache-Control sera appliqué.

En savoir plus

Image principale de Samuel Zeller