Le cache serveur garde une réponse déjà calculée pour ne pas refaire le même travail à chaque visite. Il en existe trois, et les confondre mène à purger la mauvaise couche. Le cache de page stocke le HTML. Le cache d’objets stocke des données pendant que le code tourne. L’OPcache stocke le PHP compilé. Aucun des trois ne corrige une image de 4 Mo ni un appel tiers bloquant.
Trois couches, trois effets
| Couche | Ce qui est gardé | Ce que la visite économise | Limite |
|---|---|---|---|
| OPcache | Bytecode PHP | La recompilation des fichiers | La base et le rendu ont toujours lieu |
| Cache d’objets (Redis, Memcached) | Résultat d’une requête ou d’un calcul | Une partie des allers-retours base | Le HTML est encore assemblé |
| Cache de page (Nginx, plugin, reverse proxy) | HTML complet d’une URL | PHP et la base, pour cette URL | Dangereux si le HTML est personnel |
L’OPcache s’active au niveau PHP (opcache.enable=1). Il est presque toujours souhaitable en production. Il ne se purge pas comme un plugin de cache : un déploiement de fichiers PHP doit recharger les workers ou invalider l’OPcache, sinon l’ancien bytecode continue.
Le cache d’objets sert quand la même requête revient souvent : options du site, menu, résultat d’un comptage. WordPress peut l’utiliser via un object cache persistant. Sans Redis ou Memcached, l’object cache de WordPress ne vit que le temps de la requête, donc il n’accélère pas la visite suivante.
Le cache de page est celui qui fait chuter le temps de réponse des URL publiques. C’est aussi celui qui casse un site s’il englobe le panier. Le lien avec le temps jusqu’au premier octet est direct : TTFB élevé : causes.
Ce qui ne doit jamais être servi depuis le cache de page
- Panier, tunnel de commande, compte client, tableau de bord.
- Page de formulaire dont le HTML contient un jeton de session unique.
- Réponse qui dépend du cookie d’un utilisateur connecté, sauf si vous variez la clé de cache sur ce cookie et que vous acceptez de ne presque plus rien partager.
- En-têtes
Set-Cookieposés sur une page que vous vouliez publique : ils empêchent souvent la mise en cache partagée, ou ils se retrouvent recopiés chez le visiteur suivant.
Contournement typique : le plugin ou Nginx ignore les URL /panier, /commande, /mon-compte, et toute requête dont le cookie de session boutique est présent. À l’inverse, la fiche produit et l’article de blog, identiques pour tout le monde, sont de bons candidats.
Une page publique peut quand même varier : prix selon la géolocalisation, bannière selon une campagne. Si cette variation est dans le HTML, la clé de cache doit l’inclure ou la variation doit sortir du HTML (appel séparé, non mis en cache). Sinon un visiteur voit le prix d’un autre.
Purger juste ce qui a changé
À l’enregistrement d’un article, invalidez son URL, la page d’accueil si elle le cite, et la catégorie. Laisser tout le cache tomber à chaque sauvegarde de brouillon ramène le site au calcul complet pendant les heures de rédaction.
En pratique :
- Listez les modèles publics (accueil, liste, fiche, article) et les URL exclues (compte, panier, recherche).
- Activez l’OPcache. Vérifiez qu’un déploiement recharge bien PHP.
- Si la base répète les mêmes lectures, ajoutez un cache d’objets. Le diagnostic des requêtes lentes est dans Performance de la base WordPress.
- Activez le cache de page sur les modèles publics seulement.
- Publiez un contenu test, vérifiez que l’URL publique montre le texte neuf, et qu’un panier de test ne montre pas le panier d’un autre.
- Mesurez le temps de réponse de la fiche avec et sans cache, via
curl -sI(présence ou non d’un en-tête du typeX-Cache: HIT) et un test d’URL.
Un HIT sur une page personnelle est un incident, pas une victoire. Coupez le cache de cette URL avant d’optimiser le reste.
