Le WordPress d'aujourd'hui, décodé pour les développeurs

Hébergement & serveurs

Servir les fichiers statiques avec un hachage de contenu dans le nom plutôt qu’une courte durée de cache

Un nom de fichier qui change avec son contenu permet un cache navigateur très long sans jamais servir une version périmée.

Par WordPress Développement • 21 avril 2024 • 5 min de lecture • Aucun commentaire
Servir les fichiers statiques avec un hachage de contenu dans le nom plutôt qu'une courte durée de cache

Cache-Control: public, max-age=31536000, immutable : cet en-tête, une fois posé sur un fichier CSS ou JavaScript, indique au navigateur qu’il peut le conserver pendant un an entier sans revérifier sa fraîcheur. Poser une telle durée sur un fichier nommé simplement style.css serait pourtant risqué : la moindre modification resterait invisible pour tous les visiteurs déjà passés sur le site, jusqu’à l’expiration du cache.

La solution qui permet de concilier les deux exigences, un cache agressif et une mise à jour immédiate, consiste à faire porter le changement par le nom du fichier lui-même plutôt que par sa durée de vie. C’est le principe du hachage de contenu dans le nom, une pratique bien établie qui évite toute purge manuelle après chaque déploiement.

Le principe : un nom de fichier qui dépend de son contenu

Au lieu de livrer app.css, le processus de build génère un fichier nommé app.3f9a21c.css, où la suite de caractères correspond à une empreinte calculée à partir du contenu exact du fichier. Tant que le contenu ne change pas, le nom reste identique. Dès qu’une seule ligne de CSS est modifiée, l’empreinte change intégralement, et donc le nom du fichier aussi.

Le navigateur, qui met en cache une ressource par son URL complète, considère alors app.css et app.3f9a21c.css comme deux fichiers totalement distincts. Aucune purge de cache n’est nécessaire : la nouvelle version porte simplement un nom que le navigateur n’a jamais rencontré, et va donc la télécharger sans hésitation.

Générer le hachage lors du build plutôt qu’à la main

L'essentiel à retenir : Le nom du fichier change dès que son contenu change ; Cache-Control peut alors dépasser un an sans risque ; Fini les purges manuelles de cache après chaque déploiement

Ce renommage ne se fait pas manuellement : il est produit par l’outil de build utilisé pour compiler les assets du thème ou de l’extension. Avec un outil comme esbuild ou Webpack, la configuration prévoit un motif de nommage intégrant l’empreinte de contenu :

{
  "output": {
    "filename": "[name].[contenthash].js",
    "path": "dist"
  }
}

Le résultat de la compilation produit alors un manifeste, souvent au format JSON, qui associe le nom logique du fichier (app.js) à son nom réel une fois haché (app.3f9a21c.js). Ce manifeste est ce qui permet au thème WordPress de savoir quel fichier appeler.

Faire correspondre le manifeste et l’enregistrement des scripts WordPress

Côté PHP, la fonction wp_enqueue_script() ne doit jamais pointer directement vers un nom de fichier figé dans le code du thème, puisque ce nom change à chaque build. La lecture du manifeste généré permet de résoudre dynamiquement le bon chemin :

function wpmoderne_enqueue_assets() {
    $manifest = json_decode(
        file_get_contents( get_template_directory() . '/dist/manifest.json' ),
        true
    );

    wp_enqueue_script(
        'wpmoderne-app',
        get_template_directory_uri() . '/dist/' . $manifest['app.js'],
        array(),
        null,
        true
    );
}
add_action( 'wp_enqueue_scripts', 'wpmoderne_enqueue_assets' );

Le quatrième argument de wp_enqueue_script(), habituellement utilisé pour un numéro de version, est ici volontairement laissé à null : le nom du fichier haché joue déjà ce rôle de casse-cache, et ajouter un paramètre de version supplémentaire n’apporterait rien.

Configurer un en-tête de cache très long côté serveur

Une fois cette convention en place, le bloc serveur Nginx peut appliquer une durée de cache maximale à tous les fichiers dont le nom contient une empreinte, en s’appuyant sur un motif reconnaissable dans le chemin :

location ~* \.[0-9a-f]{6,8}\.(css|js)$ {
    add_header Cache-Control "public, max-age=31536000, immutable";
}

Les fichiers qui ne suivent pas cette convention, comme les images uploadées par les auteurs depuis la médiathèque, conservent une politique de cache distincte et plus courte, puisqu’ils ne bénéficient pas du même mécanisme de renommage.

Ce que cette approche ne remplace pas

Un cache navigateur agressif, aussi bien réglé soit-il, ne dispense pas d’une réflexion plus large sur la diffusion de contenu via un CDN complet, avec ses propres règles de purge distribuée et de géo-réplication. Le hachage de contenu résout un problème précis, celui du cache local du navigateur, sans se substituer à cette couche supplémentaire.

Un nom de fichier qui change avec son contenu vaut toutes les purges manuelles du monde : il rend la question même de la fraîcheur du cache sans objet.

En résumé

Faire porter la fraîcheur du cache par le nom du fichier plutôt que par sa durée de vie permet d’appliquer sans crainte un Cache-Control d’un an complet, soit 31 536 000 secondes, sur l’ensemble des fichiers statiques compilés. Le gain se mesure directement sur les temps de chargement des visiteurs récurrents, qui ne retéléchargent plus jamais un fichier déjà en cache, tout en garantissant qu’une modification de code est visible dès la publication, sans purge manuelle ni délai d’expiration à surveiller.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Partager :

À propos de l'auteur

WordPress Développement

Développeur WordPress, passionné par Elementor, le FSE et l’automatisation par IA.

Voir tous ses articles

Dans la même veine

À lire aussi