Configurer le comportement de la mise en cache HTTP

Cet atelier de programmation vous explique comment modifier les en-têtes de mise en cache HTTP renvoyés par un serveur Web basé sur Node.js qui exécute le framework de diffusion Express. Vous découvrirez également comment vérifier que le comportement de mise en cache attendu est bien appliqué à l'aide du panneau "Network" (Réseau) des outils pour les développeurs Chrome.

Se familiariser avec l'exemple de projet

Voici les fichiers clés avec lesquels vous allez travailler dans l'exemple de projet:

  • server.js contient le code Node.js qui diffuse le contenu de l'application Web. Il utilise Express pour gérer les requêtes et les réponses HTTP. Plus spécifiquement, express.static() permet de diffuser tous les fichiers locaux dans le répertoire public. La documentation sur serve-static vous sera donc utile.
  • public/index.html est le code HTML de l'application Web. Comme la plupart des fichiers HTML, son URL ne contient aucune information de gestion des versions.
  • public/app.15261a07.js et public/style.391484cf.css sont les éléments JavaScript et CSS de l'application Web. Ces fichiers contiennent chacun un hachage dans leurs URL, correspondant à leur contenu. index.html assure le suivi de l'URL avec gestion des versions spécifique à charger.

Configurer les en-têtes de mise en cache de notre code HTML

Lorsque vous répondez à des requêtes pour des URL qui ne contiennent pas d'informations de gestion des versions, veillez à ajouter Cache-Control: no-cache à vos messages de réponse. En outre, nous vous recommandons de définir l'un des deux en-têtes de réponse supplémentaires suivants: Last-Modified ou ETag. Le index.html entre dans cette catégorie. Vous pouvez la décomposer en deux étapes.

Tout d'abord, les en-têtes Last-Modified et ETag sont contrôlés par les options de configuration etag et lastModified. Ces deux options sont définies par défaut sur true pour toutes les réponses HTTP. Dans cette configuration actuelle, vous n'avez donc pas à activer ce comportement. Mais vous pouvez quand même être explicite dans votre configuration.

Ensuite, vous devez pouvoir ajouter l'en-tête Cache-Control: no-cache, mais uniquement pour vos documents HTML (index.html, dans ce cas). Le moyen le plus simple de définir cet en-tête de manière conditionnelle consiste à écrire un setHeaders function personnalisé, dans lequel vérifier si la requête entrante concerne un document HTML.

  • Cliquez sur Remix to Edit (Remixer pour modifier) pour rendre le projet modifiable.

La configuration de diffusion statique dans server.js commence comme suit:

app.use(express.static('public'));
  • Apportez les modifications décrites ci-dessus. Vous devriez obtenir un résultat semblable à celui-ci:
app.use(express.static('public', {
  etag: true, // Just being explicit about the default.
  lastModified: true,  // Just being explicit about the default.
  setHeaders: (res, path) => {
    if (path.endsWith('.html')) {
      // All of the project's HTML files end in .html
      res.setHeader('Cache-Control', 'no-cache');
    }
  },
}));

Configurer les en-têtes de mise en cache des URL avec gestion des versions

Lorsque vous répondez à des requêtes d'URL contenant une empreinte ou des informations de version, et dont le contenu n'est jamais destiné à changer, ajoutez Cache-Control: max-age=31536000 à vos réponses. app.15261a07.js et style.391484cf.css appartiennent à cette catégorie.

En vous appuyant sur le setHeaders function utilisé à la dernière étape, vous pouvez ajouter une logique supplémentaire pour vérifier si une requête donnée concerne une URL versionnée et, le cas échéant, ajouter l'en-tête Cache-Control: max-age=31536000.

La méthode la plus efficace consiste à utiliser une expression régulière pour vérifier si l'élément demandé correspond à un modèle spécifique dont vous connaissez les hachages. Dans le cas de cet exemple de projet, il est toujours composé de huit caractères de l'ensemble de chiffres compris entre 0 et 9 et des lettres minuscules a à f (c'est-à-dire des caractères hexadécimaux). Le hachage est toujours séparé par un caractère . de chaque côté.

Une expression régulière qui correspond à ces règles générales peut être exprimée sous la forme new RegExp('\\.[0-9a-f]{8}\\.').

  • Modifiez la fonction setHeaders pour qu'elle se présente comme suit:
app.use(express.static('public', {
  etag: true, // Just being explicit about the default.
  lastModified: true,  // Just being explicit about the default.
  setHeaders: (res, path) => {
    const hashRegExp = new RegExp('\\.[0-9a-f]{8}\\.');

    if (path.endsWith('.html')) {
      // All of the project's HTML files end in .html
      res.setHeader('Cache-Control', 'no-cache');
    } else if (hashRegExp.test(path)) {
      // If the RegExp matched, then we have a versioned URL.
      res.setHeader('Cache-Control', 'max-age=31536000');
    }
  },
}));

Vérifier le nouveau comportement à l'aide des outils de développement

Une fois les modifications apportées au serveur de fichiers statiques en place, vous pouvez vérifier que les en-têtes appropriés sont définis en prévisualisant l'application en ligne avec le panneau "DevTools Network" ouvert.

  • Pour prévisualiser le site, appuyez sur Afficher l'application, puis sur Plein écran plein écran.

  • Personnalisez les colonnes affichées dans le panneau "Network" (Réseau) afin d'inclure les informations les plus pertinentes, en effectuant un clic droit sur l'en-tête de colonne:

Configurer le panneau "Network" des outils de développement

Ici, les colonnes auxquelles vous devez prêter attention sont Name, Status, Cache-Control, ETag et Last-Modified.

  • Ouvrez le panneau "Network" (Réseau) dans les outils de développement, puis actualisez la page.

Une fois la page chargée, des entrées semblables à ce qui suit doivent s'afficher dans le panneau "Network" (Réseau) :

colonnes du panneau "Network" (Réseau).

La première ligne correspond au document HTML auquel vous avez accédé. Elle est correctement diffusée avec Cache-Control: no-cache. L'état de la réponse HTTP pour cette requête est 304. Cela signifie que le navigateur savait qu'il ne devait pas utiliser immédiatement le code HTML mis en cache, mais qu'il a envoyé une requête HTTP au serveur Web à l'aide des informations Last-Modified et ETag pour voir si le code HTML présentait déjà dans son cache. La réponse HTTP 304 indique que le code HTML n'a pas été mis à jour.

Les deux lignes suivantes concernent les éléments JavaScript et CSS avec gestion des versions. Elles devraient être diffusées avec Cache-Control: max-age=31536000, avec l'état HTTP 200. En raison de la configuration utilisée, aucune requête n'est envoyée au serveur Node.js. Cliquez sur l'entrée pour afficher des détails supplémentaires, y compris que la réponse provient "(du cache du disque)".

État de réponse du réseau 200.

Les valeurs réelles des colonnes ETag et Last-Modified n'ont pas d'importance. L'important est de confirmer qu'ils sont configurés.

En résumé

Après avoir suivi les différentes étapes de cet atelier de programmation, vous êtes maintenant familiarisé avec la configuration des en-têtes de réponse HTTP sur un serveur Web basé sur Node.js à l'aide d'Express, afin d'optimiser l'utilisation du cache HTTP. Vous disposez également de la procédure à suivre pour vérifier que le comportement de mise en cache attendu est utilisé, via le panneau "Network" (Réseau) des outils de développement Chrome.