Quand une boutique affiche un prix périmé ou un panier vide, la première question posée est presque toujours la mauvaise : quel réglage a été modifié. La bonne question est ailleurs : lequel des cinq ou six caches empilés entre le serveur et le navigateur a servi cette réponse. Une boutique moderne superpose un cache de diffusion en périphérie, un cache de pages, un cache de fragments, un cache d'objets, un cache de requêtes de base et le cache du navigateur. Chacun a son périmètre, sa durée de vie et ses exclusions propres, et la stratégie de cache d'une boutique consiste avant tout à répartir clairement les rôles plutôt qu'à empiler des réglages agressifs.

Pourquoi il y a plusieurs caches

Chaque couche répond à un coût différent. Le cache de diffusion évite la traversée du réseau et supprime la latence géographique. Le cache de pages évite l'exécution complète de l'application. Le cache de fragments évite de reconstruire une partie coûteuse d'une page par ailleurs personnalisée. Le cache d'objets évite de recalculer une donnée déjà obtenue pendant la même requête ou pendant les suivantes. Le cache de requêtes évite un aller retour vers la base. Le cache du navigateur évite de retélécharger ce qui n'a pas changé. Supprimer l'un d'eux ne se compense pas par les autres, puisqu'ils ne traitent pas le même problème. À l'inverse, en activer un sans avoir réglé les précédents produit des gains décevants et des incidents inattendus, ce qui explique la mauvaise réputation dont le cache jouit dans certaines équipes.

Cette diversité explique pourquoi un même symptôme peut venir de six endroits. Un prix périmé peut provenir d'un cache de diffusion non purgé, d'une page enregistrée, d'un fragment figé, d'un objet conservé en mémoire ou d'un fichier de style que le navigateur n'a pas rechargé. La méthode de diagnostic consiste à désactiver les couches une par une, en partant de la plus externe, plutôt qu'à tout vider simultanément, geste qui règle le symptôme sans jamais identifier la cause et garantit qu'il reviendra. Cette discipline demande quelques minutes de plus et fait gagner des heures sur la durée. Elle suppose surtout de savoir quelles couches sont réellement en place, information que peu d'équipes possèdent de tête sur un site repris.

Il faut également garder à l'esprit qu'aucun de ces caches ne réduit le coût de génération réel. Ils masquent ce coût pour la plupart des requêtes, et le premier visiteur après une purge le paie intégralement, comme le paient les robots d'exploration qui demandent des pages que personne ne consulte. C'est la raison pour laquelle la mesure du temps de génération hors cache reste indispensable, sujet développé dans notre article sur la manière de mesurer le temps de réponse par gabarit. Un site dont les pages coûtent deux secondes à produire reste un site lent, quel que soit le nombre de couches empilées devant lui.

Répartition des responsabilités entre les différents caches d’un site marchand

Le cache de diffusion en périphérie

Un réseau de diffusion de contenus place des copies des ressources au plus près des visiteurs et répond sans jamais solliciter le serveur d'origine. Sur les fichiers statiques, images, feuilles de style, scripts, polices, son emploi est un gain net sans contrepartie, et il devrait être systématique sur toute boutique. Ces fichiers portent un nom incluant une empreinte de leur contenu, ce qui permet une durée de vie très longue sans risque de servir une version périmée : un changement de contenu produit un nouveau nom, donc une nouvelle ressource. Le principe est décrit dans notre article sur le CDN et son fonctionnement.

Sur les pages HTML, la question devient délicate. Faire mettre en cache une page de catégorie en périphérie divise le temps de réponse par dix pour les visiteurs éloignés, et fige simultanément tout ce que la page contient de dynamique. La règle consiste à n'autoriser cette mise en cache que sur les pages strictement communes, en excluant explicitement tout ce qui dépend d'une session, et à ne le faire qu'une fois le cache de pages du site correctement réglé. Ajouter une couche externe par dessus une configuration approximative multiplie les incidents plutôt que les performances. L'ordre de mise en place compte donc autant que le choix des outils.

Les exclusions à poser sont toujours les mêmes et doivent être écrites au niveau du service de diffusion, indépendamment de celles du site : panier, validation de commande, compte client, page de remerciement, points d'entrée programmatiques et appels asynchrones. Il faut également déclarer que la présence des témoins de session désactive la mise en cache, réglage disponible chez tous les fournisseurs sérieux et rarement activé par défaut. Sans lui, une page enregistrée alors qu'un client était connecté sera servie à tous les autres, incident rare et spectaculaire. Sa probabilité est faible et son coût, en confiance perdue, est disproportionné, ce qui justifie de traiter ce point avec le plus grand soin.

Le cache de pages du site

Cette couche enregistre la réponse produite par l'application et la ressert sans réexécuter le code. C'est celle qui apporte le gain le plus important sur une boutique, puisqu'elle supprime des dizaines de requêtes de base par affichage. C'est aussi celle qui pose le plus de questions, parce qu'elle enregistre une réponse produite pour quelqu'un et la sert à tout le monde. Les pages qu'elle ne doit jamais servir, et les raisons de chaque exclusion, sont détaillées dans notre article sur les pages à ne jamais mettre en cache sur WooCommerce.

La durée de vie mérite une réflexion par type de page plutôt qu'un réglage unique. Une fiche produit dont le stock et le prix changent plusieurs fois par jour ne se traite pas comme une page de contenu éditorial figée depuis deux ans. Le dispositif le plus robuste combine une durée de vie longue et une purge déclenchée par événement : la modification d'un produit purge sa fiche et les listes qui le contiennent, la publication d'un article purge l'accueil et sa catégorie. Cette approche évite à la fois les contenus périmés et les purges globales inutiles, qui font repayer le coût de génération sur l'ensemble du site. Elle demande en contrepartie de recenser, pour chaque type de contenu, la liste des pages à purger, travail d'une heure qui se fait une fois.

Le point de vigilance porte sur les purges déclenchées par une source externe. Une synchronisation de catalogue modifiant mille produits doit purger mille fiches et non l'intégralité du cache, sous peine de laisser le site sans cache pendant la période où il en a le plus besoin. Vérifier ce comportement fait partie des contrôles à mener sur toute boutique alimentée par un système de gestion, et le symptôme d'un défaut est un ralentissement quotidien à l'heure de la synchronisation nocturne. Le contrôle consiste à observer le taux de réponses servies depuis le cache avant et après le passage de la synchronisation.

Couche Ce qu'elle évite Exclusions principales
Diffusion en périphérie Latence réseau Tout ce qui dépend d'une session
Cache de pages Exécution de l'application Panier, commande, compte, recherche
Cache de fragments Reconstruction d'un bloc coûteux Fragments personnalisés
Cache d'objets Recalcul de données Données propres à un utilisateur
Cache de requêtes Aller retour vers la base Requêtes à résultat variable
Cache du navigateur Retéléchargement Documents HTML
Gain de temps de réponse apporté par chaque couche de cache
Cache de pages
84 %
Cache d'objets persistant
61 %
Diffusion en périphérie
47 %
Cache de fragments
29 %
Cache de requêtes de base
18 %

Réduction du temps de réponse apportée par chaque couche activée seule, sur une boutique de taille moyenne. Les gains ne s'additionnent pas, chaque couche traitant une partie du coût.

Les fragments et les objets

Le cache de fragments enregistre le rendu d'une portion de page, ce qui permet de mettre en cache l'essentiel d'un affichage tout en laissant quelques zones dynamiques. Un menu construit à partir de la base, un bloc de catégories, une liste de produits les plus vendus, un fil d'ariane sur un catalogue profond : chacun de ces éléments coûte des requêtes et ne change que rarement. Les mettre en cache individuellement, avec une durée adaptée, apporte un gain considérable sur les pages que le cache de pages ne peut pas traiter, notamment celles vues par des utilisateurs connectés. Sur un site professionnel dont l'essentiel du trafic est authentifié, cette couche devient même la principale source d'optimisation disponible.

Le cache d'objets, lui, conserve des données plutôt que du rendu. Sur WordPress, il stocke les options, les métadonnées et les résultats de requêtes, d'abord pour la durée de la requête courante et, lorsqu'un service de mémoire partagée est installé, entre les requêtes. Cette persistance change complètement le comportement d'une boutique : sans elle, chaque affichage relit en base des dizaines d'options que rien n'a modifiées. Son installation est probablement l'intervention au meilleur rapport entre effort et résultat sur une boutique dont les visiteurs sont majoritairement connectés. Son installation demande un service de mémoire partagée et une extension de liaison, soit une demi journée sur un serveur dont on dispose.

La règle d'exclusion sur ces deux couches porte sur la clé employée. Un fragment ou un objet dépendant de l'utilisateur doit inclure son identifiant dans la clé, faute de quoi le premier calcul sera servi à tout le monde. C'est la source d'incident la plus discrète de tout le dispositif, parce qu'elle ne se manifeste qu'en présence de plusieurs utilisateurs simultanés et jamais lors des tests. Une relecture systématique des clés de cache, en se demandant de quoi dépend réellement la valeur, suffit à écarter ce risque. Cette relecture doit être faite au moment de l'écriture et refaite lors de toute évolution du code concerné.

Le cache du navigateur

La dernière couche est celle que l'on maîtrise le moins bien, puisqu'elle vit chez le visiteur. Les en-têtes de réponse indiquent au navigateur combien de temps il peut conserver une ressource et dans quelles conditions il doit la revalider. Sur les fichiers statiques nommés avec une empreinte, une durée d'un an est parfaitement légitime et supprime tout retéléchargement. Sur les documents HTML, la durée doit rester très courte ou nulle, un document conservé une heure chez le visiteur affichant un prix périmé sans qu'aucune purge côté serveur ne puisse rien y faire.

C'est précisément le danger de cette couche : elle échappe à toute purge. Une erreur de configuration sur une durée de vie de document HTML se corrige côté serveur, mais les navigateurs ayant déjà enregistré la réponse continueront de la servir jusqu'à son expiration. Sur une boutique, ce scénario produit des clients voyant un ancien prix pendant plusieurs jours, situation impossible à rattraper autrement qu'en changeant les adresses. C'est la raison pour laquelle les durées longues sur les documents doivent être posées avec une prudence extrême. Quelques minutes suffisent à absorber les rafales de requêtes sans exposer à ce risque.

Le mécanisme de revalidation offre un compromis intéressant : le navigateur conserve la ressource et demande au serveur, avant de l'utiliser, si elle a changé. Le serveur répond par un code très court lorsque rien n'a bougé, ce qui économise le transfert sans risquer de servir une version périmée. Ce fonctionnement convient bien aux documents dont le contenu change parfois sans prévenir, et il coûte une requête réseau, ce qui reste bien moins cher qu'un téléchargement complet. Il repose sur une empreinte de contenu ou sur une date de modification, informations que le serveur produit sans effort particulier.

Faire cohabiter les couches

Le principe directeur consiste à attribuer un rôle unique à chaque couche et à écrire cette répartition quelque part. Une boutique où le cache de pages et le service de diffusion appliquent chacun leurs propres exclusions, formulées différemment, finit par présenter des comportements incohérents selon la page consultée. La bonne pratique consiste à définir la liste des chemins non cachables une seule fois, puis à la transposer dans chaque couche, en vérifiant que la transposition est fidèle. Cette liste doit vivre avec le code du projet et non dans l'interface de chaque outil. Elle constitue le document de référence auquel on revient à chaque incident, et sa simple existence fait gagner un temps considérable.

Les durées de vie doivent également être cohérentes entre les couches. Une page conservée dix minutes en périphérie et deux heures par le cache du site produit une situation où la purge du second n'a aucun effet visible pendant dix minutes, ce qui déroute complètement lors d'un diagnostic. La règle simple consiste à faire décroître les durées de l'intérieur vers l'extérieur, et à s'assurer que toute purge se propage vers les couches externes, ce que les services de diffusion permettent par une interface de programmation. Cette propagation doit être testée une fois, en purgeant une page et en vérifiant qu'elle est bien régénérée en périphérie.

Enfin, il faut décider qui purge quoi. Une purge globale déclenchée à chaque enregistrement de contenu, comportement par défaut de plusieurs extensions, annule l'essentiel du bénéfice sur un site actif. Une purge ciblée, portant sur la page modifiée et sur les listes qui la contiennent, demande un peu de configuration et change radicalement le comportement du site. Ce réglage figure parmi les premiers à examiner sur une boutique dont on constate que le cache semble ne jamais servir. Il explique à lui seul une bonne part des déceptions rencontrées après l'installation d'une extension de cache.

Vérifier ce qui se passe réellement

Le contrôle se fait dans les en-têtes de réponse, qui indiquent pour chaque couche si la réponse provenait du cache. Un parcours de quelques pages représentatives, en lisant ces en-têtes, donne en cinq minutes une image complète du fonctionnement. Une fiche produit doit être servie depuis le cache à la deuxième visite, une page de panier ne doit jamais l'être, et un fichier statique doit répondre depuis la périphérie. Ces trois vérifications suffisent à écarter la grande majorité des configurations dangereuses. Elles se font avec les outils de développement du navigateur, sans installer quoi que ce soit.

Le second contrôle porte sur la cohabitation avec les sessions. Ouvrir deux fenêtres de navigation privée, ajouter un article au panier dans la première et vérifier que la seconde reste vide, teste l'ensemble de la chaîne d'un coup. Ce test doit être refait après chaque modification de configuration et après chaque mise à jour d'une extension de cache, deux moments où les réglages sont régulièrement réinitialisés sans avertissement. Trois minutes de contrôle valent mieux qu'une réclamation client sur un panier disparu.

Le troisième contrôle est un suivi dans la durée. Le taux de réponses servies depuis le cache, relevé chaque semaine, indique si le dispositif fonctionne réellement. Une chute de ce taux signale une purge trop fréquente ou une exclusion trop large, deux situations qui dégradent les performances sans produire d'incident visible. Ce chiffre se lit dans les statistiques du service de diffusion ou dans celles de l'extension de cache, et il mérite d'être suivi au même titre que le temps de réponse. Un taux durablement inférieur à quatre vingts pour cent sur les pages publiques signale presque toujours un réglage à revoir. Ce taux se lit en même temps que la liste des adresses les plus souvent régénérées, seul moyen de distinguer une exclusion trop large d'un simple manque de trafic sur des pages peu consultées.