J'adore votre cache ❤️

Les utilisateurs qui chargent votre site une deuxième fois utiliseront leur cache HTTP. Assurez-vous donc qu'il fonctionne correctement.

Ce post accompagne la vidéo Aimez votre cache, qui fait partie du contenu étendu du Chrome Dev Summit 2020. N'hésitez pas à regarder cette vidéo :

Lorsque les utilisateurs chargent votre site une deuxième fois, leur navigateur utilise les ressources de son cache HTTP pour accélérer le chargement. Toutefois, les normes de mise en cache sur le Web remontent à 1999 et sont définies de manière assez générale : déterminer si un fichier, comme CSS ou une image, peut être extrait à nouveau du réseau ou chargé à partir du cache, n'est pas très précis.

Dans cet article, je vais vous présenter une valeur par défaut raisonnable et moderne pour la mise en cache, qui n'effectue en fait aucune mise en cache. Mais il ne s'agit que de la valeur par défaut. Il est bien sûr plus nuancé que de simplement "désactiver". Lisez la suite.

Objectifs

Lorsque vous chargez un site pour la deuxième fois, vous avez deux objectifs:

  1. Veillez à ce que vos utilisateurs disposent de la version la plus récente disponible. Si vous avez apporté des modifications, elles devraient être répercutées rapidement.
  2. Effectuez l'opération 1 en extrayant le moins possible de données du réseau.

Au sens le plus large, vous ne voulez n'envoyer que la plus petite modification à vos clients lorsqu'ils chargent à nouveau votre site. Et structurer votre site pour assurer la distribution la plus efficace de toute modification est un défi (plus d'informations ci-dessous et dans la vidéo).

Cela dit, vous avez également d'autres paramètres à prendre en compte lorsque vous envisagez la mise en cache. Vous avez peut-être décidé de laisser le cache HTTP du navigateur d'un utilisateur conserver votre site pendant une longue période afin qu'aucune requête réseau ne soit requise pour l'afficher. Ou vous avez créé un service worker qui desservira un site entièrement hors connexion avant de vérifier s'il est à jour. Il s'agit d'une option extrême, qui est valide et utilisée pour de nombreuses expériences Web semblables à des applications en premier plan hors connexion. Toutefois, le Web n'a pas besoin d'être extrêmement basé sur le cache, ni même complètement basé sur le réseau.

Contexte

En tant que développeurs Web, nous sommes tous habitués à l'idée d'avoir un "cache obsolète". Mais nous savons, presque instinctivement, quels outils sont disponibles pour résoudre ce problème : effectuez une "actualisation forcée", ouvrez une fenêtre de navigation privée ou utilisez une combinaison des outils pour les développeurs de votre navigateur pour effacer les données d'un site.

Les utilisateurs ordinaires sur Internet n'ont pas ce luxe. Bien que nous ayons pour objectif principal de faire en sorte que nos utilisateurs profitent pleinement de leur deuxième chargement, il est également très important de s'assurer qu'ils ne souffrent pas ou ne restent pas bloqués. (Regardez la vidéo si vous voulez m'entendre parler de la façon dont nous avons failli bloquer le site web.dev/live.)

Pour information, l'une des raisons les plus courantes d'un "cache obsolète" est en réalité la mise en cache par défaut datant de 1999. Il repose sur l'en-tête Last-Modified :

Diagramme illustrant la durée pendant laquelle différents composants sont mis en cache par le navigateur d'un utilisateur
Les composants générés à des moments différents (en gris) seront mis en cache pendant des durées différentes. Une deuxième importation peut donc obtenir une combinaison de composants mis en cache et de composants frais.

Chaque fichier que vous chargez est conservé pendant 10 % supplémentaires de sa durée de vie actuelle, comme le voit votre navigateur. Par exemple, si index.html a été créé il y a un mois, il sera mis en cache par votre navigateur pendant encore trois jours environ.

C'était une idée bien intentionnée à l'époque, mais compte tenu de la nature étroitement intégrée des sites Web d'aujourd'hui, ce comportement par défaut signifie qu'il est possible qu'un utilisateur dispose de fichiers conçus pour différentes versions de votre site Web (par exemple, le code JavaScript de la version du mardi et le code CSS de la version du vendredi), car ces fichiers n'ont pas été mis à jour exactement au même moment.

Le chemin bien éclairé

Une méthode moderne par défaut pour la mise en cache consiste à n'effectuer aucune mise en cache et à utiliser des CDN pour rapprocher votre contenu des utilisateurs. Chaque fois qu'un utilisateur charge votre site, il accède au réseau pour vérifier s'il est à jour. Cette requête aura une latence faible, car elle sera fournie par un CDN situé géographiquement à proximité de chaque utilisateur final.

Vous pouvez configurer votre hébergeur Web pour qu'il réponde aux requêtes Web avec cet en-tête:

Cache-Control: max-age=0,must-revalidate,public

Cela signifie que le fichier n'est valide que pendant un court laps de temps et que vous devez le valider sur le réseau avant de pouvoir l'utiliser à nouveau (sinon, il n'est que "suggéré").

Ce processus de validation est relativement peu coûteux en termes d'octets transférés. Si un fichier image volumineux n'a pas changé, votre navigateur recevra une petite réponse 304. Toutefois, il entraîne une latence, car un utilisateur doit toujours accéder au réseau pour le savoir. C'est l'inconvénient principal de cette approche. Il peut fonctionner très bien pour les utilisateurs disposant de connexions rapides dans les pays développés, où votre CDN de choix offre une couverture optimale, mais pas pour ceux qui utilisent des connexions mobiles plus lentes ou une infrastructure de mauvaise qualité.

Quoi qu'il en soit, il s'agit d'une approche moderne qui est utilisée par défaut sur un CDN populaire, Netlify, mais qui peut être configurée sur presque tous les CDN. Pour Firebase Hosting, vous pouvez inclure cet en-tête dans la section d'hébergement de votre fichier firebase.json :

"headers": [
  // Be sure to put this last, to not override other headers
  {
    "source": "**",
    "headers": [ {
      "key": "Cache-Control",
      "value": "max-age=0,must-revalidate,public"
    }
  }
]

Je vous suggère donc de définir cette valeur par défaut, mais ce n'est qu'une suggestion. Lisez la suite pour découvrir comment intervenir et mettre à niveau les valeurs par défaut.

URL avec empreinte numérique

En incluant un hachage du contenu du fichier dans le nom des composants, des images, etc. diffusés sur votre site, vous pouvez vous assurer que ces fichiers auront toujours un contenu unique. Par exemple, les fichiers seront nommés sitecode.af12de.js. Lorsque votre serveur répond aux requêtes pour ces fichiers, vous pouvez demander aux navigateurs de vos utilisateurs finaux de les mettre en cache pendant une longue période en les configurant avec l'en-tête suivant:

Cache-Control: max-age=31536000,immutable

Cette valeur correspond à une année, en secondes. Et selon les spécifications, cela équivaut à "pour toujours".

Il est important de noter que ne générez pas ces hachages à la main : cela représente trop de travail manuel ! Vous pouvez utiliser des outils tels que Webpack, Rollup, etc. pour vous aider. Pour en savoir plus, consultez le rapport sur les outils.

N'oubliez pas que le code JavaScript n'est pas le seul à pouvoir bénéficier des URL avec empreintes digitales. Des éléments tels que des icônes, des CSS et d'autres fichiers de données immuables peuvent également être nommés de cette façon. (N'oubliez pas de regarder la vidéo ci-dessus pour en savoir plus sur le fractionnement du code, qui vous permet de publier moins de code chaque fois que votre site change.)

Quelle que soit la méthode de mise en cache de votre site, ces types de fichiers avec empreinte digitale sont extrêmement utiles pour tout site que vous pourriez créer. La plupart des sites ne changent pas à chaque version.

Bien entendu, nous ne pouvons pas renommer nos pages "conviviales" destinées aux utilisateurs en renommant votre fichier index.html en index.abcd12.html. Ce n'est pas faisable, vous ne pouvez pas dire aux utilisateurs d'accéder à une nouvelle URL chaque fois qu'ils chargent votre site. Ces URL "amicales" ne peuvent pas être renommées ni mises en cache de cette manière, ce qui me conduit à trouver un compromis.

Solution intermédiaire

Il y a évidemment de la place pour un terrain d’entente pour la mise en cache. J'ai présenté deux options extrêmes : ne jamais mettre en cache ou mettre en cache pour toujours. Vous souhaiterez peut-être mettre en cache un certain nombre de fichiers pendant un certain temps, comme les URL "amicales" que j'ai mentionnées ci-dessus.

Si vous souhaitez mettre en cache ces URL "amicales" et leur code HTML, il est utile de réfléchir aux dépendances qu'elles incluent, à la façon dont elles peuvent être mises en cache et à l'impact que la mise en cache de leurs URL pendant un certain temps peut avoir sur vous. Examinons une page HTML qui inclut une image comme celle-ci :

<img src="/images/foo.jpeg" loading="lazy" />

Si vous mettez à jour ou modifiez votre site en supprimant ou en modifiant cette image chargée de manière différée, les utilisateurs qui consultent une version mise en cache de votre code HTML peuvent voir une image incorrecte ou manquante, car ils ont toujours mis en cache l'/images/foo.jpeg d'origine lorsqu'ils reviennent sur votre site.

Si vous faites attention, cela ne vous affectera peut-être pas. Toutefois, il est important de se rappeler que votre site, lorsqu&#39;il est mis en cache par vos utilisateurs finaux, n&#39;existe plus uniquement sur vos serveurs. Il peut plutôt exister en morceaux dans les caches des navigateurs de vos utilisateurs finaux.

En règle générale, la plupart des guides sur la mise en cache parlent de ce type de paramètre : souhaitez-vous mettre en cache pendant une heure, plusieurs heures, etc. Pour configurer ce type de cache, utilisez un en-tête comme celui-ci (qui met en cache pendant 3 600 secondes, soit une heure) :

Cache-Control: max-age=3600,immutable,public

Un dernier point. Si vous créez des contenus d'actualité auxquels les utilisateurs n'ont généralement accès qu'une seule fois (comme des articles d'actualité), je pense qu'ils ne doivent jamais être mis en cache. Vous devez utiliser notre valeur par défaut appropriée ci-dessus. Je pense que nous surestimons souvent la valeur du cache par rapport au désir de l'utilisateur de toujours voir les contenus les plus récents et les plus intéressants, comme une mise à jour critique sur une actualité ou un événement en cours.

Options non HTML

En plus du code HTML, voici d'autres options pour les fichiers qui se situent entre les deux:

  • En règle générale, recherchez les composants qui n'affectent pas les autres.

    • Par exemple, évitez d'utiliser le langage CSS, car il modifie le rendu de votre code HTML.
  • Images de grande taille utilisées dans des articles d'actualité

    • Vos utilisateurs ne consulteront probablement pas un article plus d'une poignée de fois. Par conséquent, ne mettez pas en cache des photos ou des images principales indéfiniment et ne gaspillez pas d'espace de stockage.
  • Un élément qui représente un élément qui lui-même est associé à une durée de vie.

    • Les données JSON sur la météo ne sont peut-être publiées qu'une fois par heure. Vous pouvez donc mettre en cache le résultat précédent pendant une heure, car il ne changera pas pendant cette période.
    • Les compilations d'un projet Open Source peuvent être limitées en débit. Mettez donc en cache une image de l'état de compilation jusqu'à ce que l'état puisse changer.

Résumé

Lorsque les utilisateurs chargent votre site une deuxième fois, vous avez déjà obtenu un vote de confiance : ils veulent revenir et profiter davantage de ce que vous proposez. À ce stade, il ne s'agit pas toujours de réduire ce temps de chargement. De nombreuses options sont à votre disposition pour vous assurer que votre navigateur effectue uniquement le travail nécessaire pour offrir une expérience rapide et à jour.

La mise en cache n'est pas un concept nouveau sur le Web, mais elle a peut-être besoin d'une valeur par défaut raisonnable. Envisagez d'en utiliser une et d'activer fortement de meilleures stratégies de mise en cache lorsque vous en avez besoin. Merci de votre attention,

Voir aussi

Pour obtenir un guide général sur le cache HTTP, consultez Empêcher les requêtes réseau inutiles avec le cache HTTP.