Hiérarchies de mise en cache fournissent les temps de chargement les plus rapides lorsque j'utilise chaque couche de manière ciblée : opcode, page, navigateur et Edge. Je montre en étapes claires comment combiner ces couches, éviter les conflits et définir les configurations de telle sorte que les requêtes soient plus courtes et que le TTFB diminue visiblement.
Points centraux
Afin d'avoir une vue d'ensemble, je commence par résumer les thèmes clés et je les classe directement en fonction des objectifs de performance. J'explique tous les niveaux avec des paramètres concrets, afin que la mise en œuvre réussisse sans détours. Je délimite proprement les parties dynamiques afin de préserver la personnalisation. J'optimise les en-têtes et les clés de cache de manière à ne pas créer de volume inutilement élevé dans le cache. Enfin, je rassemble le tout en une chaîne cohérente, de sorte que chaque appel emprunte la route la plus rapide.
- Opcode accélère PHP
- Cache des pages raccourci TTFB
- Navigateur économise la bande passante
- Edge réduit la latence
- Orchestration évite les conflits
Que signifie concrètement „hiérarchies de mise en cache“ ?
J'entends par Hiérarchie la mise en cache échelonnée du noyau du serveur jusqu'au terminal. Chaque couche répond à une question différente : le serveur doit-il recompiler le code, PHP doit-il rendre la page à nouveau, le navigateur doit-il recharger les actifs ou un nœud Edge livre-t-il un contenu déjà prêt près de l'utilisateur. J'évite les doubles emplois en harmonisant les niveaux et en attribuant des responsabilités claires. Je réduis ainsi la charge du processeur, les requêtes de backend et la latence du réseau sans perdre de fonctionnalité. Je trouve une brève introduction aux niveaux dans ce guide compact : Niveaux de mise en cache simples.
Mise en cache de l'opcode : accélérer PHP immédiatement
À l'adresse suivante : Opcode-Caching, je garde le bytecode PHP compilé en RAM et je m'épargne l'analyse répétée. Cela accélère chaque requête qui touche PHP, en particulier les charges de travail CMS comme WordPress. J'active OPcache et je dimensionne la mémoire de manière suffisamment généreuse pour que les scripts fréquents ne soient jamais supplantés. Je mets en place une revalidation modérée afin que les modifications restent visibles en temps voulu, sans devoir vérifier trop souvent. Je fais ainsi baisser sensiblement la charge du processeur et les temps de réponse.
Je règle les paramètres typiques de l'OPcache dans le php.ini de manière délibérément conservatrice, j'observe le taux de réussite et je l'adapte si nécessaire. Je maintiens le nombre de fichiers accélérés à un niveau suffisamment élevé pour que le projet puisse être entièrement hébergé. J'utilise le preloading pour les classes centrales afin que même les démarrages à froid se déroulent plus rapidement. Je déploie les modifications avec une réinitialisation du cache afin de ne pas risquer des états incohérents. Le bloc de configuration me sert de point de départ et non de dogme rigide.
opcache.enable=1
opcache.memory_consumption=256
opcache.max_accelerated_files=20000
opcache.validate_timestamps=1
opcache.revalidate_freq=2
Je vérifie régulièrement les OPcache-Seule la mesure permet de savoir si le cache fonctionne ou non. Les tableaux de bord de l'hébergement ou les pages d'état PHP m'aident à minimiser le nombre d'échecs. J'évite les valeurs de mémoire trop petites qui entraînent des évictions. De même, j'évite les validations trop rares afin que les modifications productives ne restent pas bloquées. Cet équilibre me permet de travailler de manière efficace et sûre.
Mise en cache des pages : HTML sans temps d'attente
À l'adresse suivante : Cache des pages j'enregistre le HTML terminé, de sorte que PHP et la base de données ne fonctionnent plus du tout. Cela réduit considérablement le TTFB et permet de faire les plus grands sauts en charge. J'exclue systématiquement les chemins personnalisés comme le panier, le checkout et les comptes d'utilisateur. En même temps, j'encapsule les petites parties dynamiques via AJAX ou Edge-Side-Includes, afin que le reste puisse sortir en dur du cache. Ainsi, le site reste rapide sans perdre son individualité.
Je décide si j'utilise la mise en cache au niveau du serveur ou si je travaille avec un plugin. Sur le serveur, j'obtiens le meilleur Latence, Les plugins me donnent un contrôle flexible dans le CMS. Des mécanismes de préchargement préremplissent le cache pour que les premiers appels n'attendent pas. Je nettoie les entrées orphelines par des règles de purge lorsque j'actualise les contenus. Pour les domaines particulièrement onéreux, je combine en outre le cache d'objets afin que les accès à la base de données soient moins fréquents.
Mise en cache du navigateur : garder les assets en local
À l'adresse suivante : Navigateur-Je laisse les fichiers statiques tels que les images, CSS et JS en local dans le cache. Les visiteurs récurrents ne chargent alors presque plus rien et le serveur reste libre. Je fixe des valeurs max-age longues pour les actifs immuables, que j'assortis d'un versionnement des noms de fichiers. J'attribue aux points de terminaison dynamiques des durées courtes ou des must-revalidate pour que l'application reste à jour. Cela me permet de réduire la bande passante et d'optimiser la vitesse perçue.
Je veille à un mélange propre de contrôle du cache, d'ETag et de Last-Modified. Pour les fichiers immuables, j'utilise immutable pour que le navigateur ne vérifie pas inutilement. Pour les ressources avec des mises à jour fréquentes, j'utilise des requêtes conditionnelles par ETag. J'évite les en-têtes ambigus, car les signaux contradictoires entraînent des malentendus. Je garde le contrôle directement dans le serveur web ou via un plug-in CMS, en fonction de mon environnement.
Edge-Caching : proximité avec l'utilisateur
Sur Edge-Dans les réseaux, je livre le contenu dans des PoP globaux, ce qui minimise la latence et lisse les pics. Le HTML, les images et les API peuvent être servis à proximité de l'utilisateur, en fonction du jeu de règles. Je travaille avec des clés de cache qui ne contiennent que des variables nécessaires afin de limiter la fragmentation. Des règles telles que stale-while-revalidate et stale-if-error garantissent que les utilisateurs voient immédiatement une copie valide, même si Origin est en train de chauffer. Les groupes cibles internationaux en profitent particulièrement, car les temps de routage sont sensiblement réduits.
Je sépare les variantes lorsque le mobile et le desktop diffèrent fortement. Je laisse délibérément de côté le checkout et la zone de compte pour éviter les collisions avec les sessions et les cookies. Je contrôle régulièrement le taux de réussite et j'adapte les TTL jusqu'à ce que les taux optimaux soient atteints. Pour un approfondissement pratique, voir Guide de la mise en cache d'Edge en mettant l'accent sur la latence et les chemins de réseau. Je garde à portée de main des stratégies de purge propres pour que les mises à jour soient immédiatement efficaces dans le monde entier.
Définir correctement les en-têtes HTTP
Le En-tête contrôler jusqu'où les contenus peuvent voyager et quand ils doivent être revalidés. Avec Cache-Control, je détermine la visibilité, la durée de vie et les obligations de revalidation. ETag identifie une ressource de manière unique et permet des requêtes If-None-Match. Last-Modified fournit une solution de repli pour les clients qui ignorent ETags. Je garde la combinaison claire pour que le client, le CDN et Origin partagent les mêmes attentes.
J'utilise l'aperçu suivant comme référence pratique lors de la configuration. Je vérifie chaque ligne par rapport au type de ressource et au comportement de modification. Pour les fichiers statiques, je définis des valeurs max-age longues avec immutable. Pour les contenus fréquemment mis à jour, je réduis la durée et je m'appuie sur des requêtes conditionnelles. Ainsi, le chemin des données reste efficace et correct.
| En-tête | Fonction |
|---|---|
| Contrôle du cache | Contrôle la durée, la visibilité, la revalidation (par ex. max-age, public, must-revalidate) |
| ETag | Identification univoque d'une version, base des appels conditionnels |
| Dernière modification | Horodatage comme alternative à ETag, sert à la validation |
Invalidation de la mémoire cache et stratégies de fraîcheur
Je prévois Invalidation aussi soigneusement que la mise en cache elle-même. La purge ponctuelle par ID, tag ou chemin évite les fuites complètes qui entraînent des coûts. Lors du déploiement, je ne purge que ce qui a vraiment changé. Stale-while-revalidate permet aux utilisateurs de rester rapides, tandis que l'arrière-plan charge des copies fraîches. Stale-if-error intercepte les pannes à l'origine sans dégrader l'expérience utilisateur.
Je combine des TTL courts avec un taux de réussite élevé lorsque les contenus tournent fréquemment. Pour les archives, les médias et les bibliothèques, je choisis des temps longs, je versionne les noms de fichiers et je supprime les charges de contrôle. Les tableaux de bord du CDN ou du serveur me montrent où les buckets de cache sont sous-dimensionnés. J'adapte alors le nombre de slots et la taille des objets. Ce peaufinage constant fait la différence au quotidien.
Clés de cache, cookies et Vary
Avec des Clés je limite le nombre de variantes. Seuls les paramètres qui modifient réellement le résultat sont inclus dans la clé. J'utilise délibérément les en-têtes Vary, par exemple après l'encodage Accept ou les classes User-Agent, si nécessaire. Un trop grand nombre de cookies dans la clé désorganise le cache et diminue le taux de réussite. Je nettoie les cookies inutilisés et règle les paramètres qui servent au suivi hors de la clé.
Si je dois varier les langues, les devises ou les mises en page, j'utilise des clés ciblées comme lang=fr ou currency=EUR. Je limite cette diversité aux cas dont j'ai vraiment besoin. Pour les tests A/B, je ne sépare que les segments qui présentent des différences de contenu. Je gère tout le reste côté client ou par Edge-Logic sans explosion de clés. C'est ainsi que je garde le cache global efficace.
Cache d'objets et transitoires
A Objet-Le cache réduit les requêtes coûteuses dans la base de données en conservant les résultats en mémoire. Pour WordPress, je choisis Redis ou Memcached et garantis ainsi un accès rapide aux options, requêtes et sessions fréquemment demandées. J'utilise des transients pour conserver temporairement des calculs coûteux. Je nettoie ces valeurs lors du déploiement lorsque les dépendances changent. Ainsi, le site reste dynamique tout en étant rapide.
Pour les tailles de projet avec une charge de données intensive, cette comparaison m'aide : Redis vs Memcached. J'y identifie les points forts des deux systèmes en fonction de la charge de travail. Je dimensionne la RAM et j'examine les stratégies d'éviction pour que les objets rarement utilisés fassent de la place. Le suivi des taux de réussite/d'échec montre si la configuration est viable. Ce niveau complète idéalement le cache des pages.
Combinaison : la chaîne optimisée
Je combine les Niveaux de manière à ce que chaque requête prenne le chemin le plus court. OPcache accélère la génération lorsque le HTML est vraiment nouveau. Le cache de page fournit un balisage prêt à l'emploi pour les visiteurs anonymes. La mise en cache du navigateur empêche les transferts répétés d'actifs et Edge distribue le contenu de manière globale. Enfin, une stratégie de purge et de versionnement propre permet aux mises à jour de prendre effet immédiatement.
Je garde le tableau suivant à portée de main comme antisèche lorsque j'agis sur les vis de réglage. Je lis la colonne „Configuration“ comme une liste de choses à faire lors de la mise en œuvre. Ce faisant, je veille à ce que les niveaux se complètent et ne se neutralisent pas mutuellement. Ainsi, l'architecture globale reste claire et performante. Cette vue d'ensemble permet d'éviter les erreurs lors de la planification.
| Niveau de la mémoire cache | Avantage | Contenu typique | Configuration |
|---|---|---|---|
| Opcode | Exécution rapide de PHP | Code byte PHP | php.ini, panneau de serveur |
| Page | TTFB faible | HTML prêt à l'emploi | Niveau du serveur ou du plugin |
| Navigateur | Réutilisation locale | CSS, JS, images | En-tête HTTP, versionnement |
| Edge | Proximité globale | HTML et actifs | Règles CDN, Keys, Purge |
Mesure : TTFB, LCP et taux de réussite
Je mesure TTFB, pour voir à quelle vitesse le premier octet arrive. LCP me montre si le contenu visible apparaît à temps. Avec l'analyse du cache, je vérifie les taux de réussite et j'identifie les trajets où les échecs se multiplient. Je corrèle les métriques avec les déploiements, la charge des crawlers et les pics de trafic. Seuls les chiffres me montrent où je dois resserrer les boulons.
Je consigne les en-têtes de réponse tels que l'âge et l'état du cache CF afin de rendre visible le succès de Edge. Les journaux de serveur me disent si le cache de la page fonctionne correctement. En cas d'écarts importants, je recherche les cookies, les paramètres de requête ou Vary qui fragmentent le cache. Je teste des variantes avec et sans connexion. De cette manière, je trouve rapidement les leviers pour une vitesse stable.
Erreurs typiques et corrections
Trop de Variantes dans le cache sont un frein fréquent. Je réduis les paramètres de requête dans la clé et je neutralise les paramètres de suivi. Les en-têtes contradictoires, tels que no-store et max-age long, sont également un classique. Des purges vides ou incorrectes peuvent également donner l'impression que le cache ne fonctionne pas. Avec des règles et des logs clairs, je résous rapidement ces problèmes.
Un autre sujet est celui des plugins qui écrivent des contenus dynamiques en dur dans le HTML. Je déplace de tels éléments dans des points finaux fragmentés qui mettent en cache ou chargent fraîchement de manière indépendante. Souvent, les cookies bloquent involontairement le cache de l'Edge ; je supprime les cookies inutiles à temps. Un mauvais versionnement oblige les navigateurs à recharger sans cesse ; je numérote les fichiers de manière cohérente. Ainsi, le pipeline reste propre et résilient.
Arbre de décision : qui répond à une demande ?
J'établis un processus décisionnel clair pour déterminer quel niveau peut fournir. Cela évite les hits d'origine inutiles et réduit le TTFB de manière reproductible.
- 1) La ressource est-elle immuable (fichier versionné) ? Cache du navigateur avec max-age long et immuable.
- 2) La requête est-elle anonyme, GET et sans cookies sensibles ? Edge/cache de page avec public, s-maxage et stale-While-Revalidate.
- 3) La requête contient-elle des cookies d'authentification, des en-têtes d'autorisation ou est-elle POST ? Origin, avec cache d'objets en option.
- 4) L'URL ne contient-elle que des paramètres cosmétiques (utm, fbclid) ? Je les supprime de la clé de cache.
- 5) A-t-on besoin de petites parties en direct (par ex. compte du panier d'achat) ? Fragmenté via AJAX ou ESI.
// Pseudo-logique
if (immutable_asset) return browser_cache ;
if (is_get && is_anonymous && cacheable) return edge_or_page_cache ;
if (needs_fragment) return cached_html + dynamic_fragment ;
return origin_with_object_cache ; Maîtriser la fragmentation : ESI, AJAX et rendu partiel
J'isole les îlots dynamiques pour que le reste puisse faire une mise en cache difficile. ESI convient pour les inserts côté serveur (par exemple, les blocs personnalisés), AJAX pour les points de rechargement côté client. Il est important que les fragments reçoivent leurs propres TTL courts, afin qu'ils restent à jour sans invalider l'ensemble du document.
- Base statique : TTL long, public, s-maxage, stale-while-revalidate.
- Fragment dynamique : TTL court, must-revalidate ou no-store si lié à une personne.
- Cas d'erreur : stale-if-error sur l'enveloppe HTML empêche les pages blanches.
// Exemple d'en-tête pour l'enveloppe HTML
Contrôle du cache : public, max-age=0, s-maxage=600, stale-while-revalidate=60, stale-if-error=86400
// Exemple d'en-tête pour un fragment personnel
Contrôle du cache : private, no-store Éviter les tempêtes de cache et gérer l'échauffement
J'évite les effets de troupeau, où de nombreux miss simultanés inondent l'origine. Soft-TTL/Hard-TTL, coalescence de requêtes et verrouillage sont mes outils. J'utilise des préchargeurs qui réchauffent cycliquement les plans de site ou les chemins importants et échelonnent les TTL pour que tout n'expire pas en même temps.
- Soft-TTL : un worker peut renouveler des objets expirés, alors que d'autres consommateurs reçoivent encore des stale.
- Coalescence : les demandes simultanées sur la même clé sont fusionnées.
- Des TTL échelonnés : Les pages critiques reçoivent des temps d'exécution décalés afin de lisser les vagues de purge.
// Exemple de durées échelonnées
/home, /catégorie/* -> s-maxage=900
/article/* -> s-maxage=1800
/recherche -> s-maxage=120, stale-while-revalidate=30 Aligner proprement le design TTL dans la chaîne
Je règle les TTL du navigateur, de Edge et d'Origin de manière à ce que la revalidation se fasse là où elle est la plus avantageuse. Pour le HTML, je compte sur s-maxage dans Edge et je garde max-age bas dans Browser pour garantir des purges rapides. Pour les actifs, je renverse la situation : des TTL très longs dans le navigateur, car la versionnalisation garantit l'actualité.
// HTML
Contrôle du cache : public, max-age=0, s-maxage=600, stale-while-revalidate=60
// Actifs versionnés
Contrôle du cache : public, max-age=31536000, immutable J'évite les indications contradictoires comme no-cache avec immutable. Des règles claires créent des résultats cohérents dans toute la hiérarchie.
Compression, HTTP/2/3 et priorisation
J'active Gzip/Brotli et je définis correctement l'en-tête Vary afin de séparer proprement les variantes. Avec HTTP/2/3, je profite du multiplexage et de la priorisation ; cela réduit le head-of-line blocking lorsque de nombreux assets sont chargés en parallèle.
# Exemple NGINX
gzip on ;
gzip_types text/css application/javascript application/json image/svg+xml ;
brotli on ;
brotli_types text/css application/javascript application/json image/svg+xml ;
add_header Vary "Accept-Encoding" always ;
# TTL long du navigateur pour les assets
location ~* .(css|js|svg|woff2|jpg|png)$ {
expire 1y ;
add_header Contrôle de cache "public, max-age=31536000, immutable" ;
} Authentification, cookies et sécurité
Je ne mets jamais en cache publiquement des contenus personnels. Je marque les requêtes avec des en-têtes d'autorisation ou des cookies de session comme étant privées ou je contourne le cache de périphérie de manière ciblée. Parallèlement, je ne mets en liste blanche que les cookies essentiels afin que la clé de cache reste légère.
- Zones de connexion/compte : Contrôle du cache : private ou no-store.
- Pages HTML publiques : public, s-maxage ; éviter le cookie de configuration.
- Hygiène des cookies : supprimer les cookies non pertinents (par ex. tracking) de la clé.
// Logique de type VCL
if (req.http.Authorization) { return(pass) ; }
if (req.http.Cookie ~ "session=") { return(pass) ; }
// Ne mettre que les cookies nécessaires dans la clé
unset req.http.Cookie : ".*" ;
Mise en cache efficace des points finaux de l'API et de la recherche
Je fais une distinction stricte entre les méthodes : GET peut être mis en cache, POST ne l'est généralement pas. Pour les requêtes de recherche fréquentes, je définis des valeurs s-maxage courtes plus stale-while-revalidate afin de lisser les temps de réaction. Les réponses contenant 4xx/5xx erreurs ne sont que brièvement mises en cache, voire pas du tout, afin que les corrections soient immédiatement prises en compte.
// Exemple d'en-tête pour l'API GET publique
Contrôle du cache : public, max-age=0, s-maxage=120, stale-while-revalidate=30
// Mettre en cache les erreurs avec parcimonie
Contrôle de cache : public, s-maxage=10 Observabilité : en-têtes, logs et contrôle TTFB
J'utilise l'inspection des en-têtes et les logs pour rendre la chaîne transparente. L'âge, les indicateurs hit/ miss et l'état de l'upstream me montrent où le temps est perdu. Grâce à des outils simples, je vérifie le TTFB de manière reproductible et je trouve les valeurs aberrantes.
# Mesurer le TTFB
curl -o /dev/null -s -w "TTFB : %{time_starttransfer}sn" https://example.org
# Vérifier l'en-tête
curl -I https://example.org | sed -n '1,20p' # Log NGINX avec statut du cache
log_format timed '$remote_addr "$request" $status $body_bytes_sent '
'$upstream_cache_status $upstream_response_time $request_time' ;
access_log /var/log/nginx/access.log timed ; Je compare les données des logs avec les déploiements et les purges. Des pics élevés de mauvaise performance juste après les déploiements indiquent un manque d'échauffement ou des TTL trop courts. Si Age reste bas en permanence, je vérifie si des cookies contournent involontairement le cache de l'edge.
Déploiement : versionnage et purges roulantes
J'intègre des versions dans les noms de fichiers (par exemple app.9f3c1.js) pour permettre au cache du navigateur d'être agressif. Pour le HTML, j'utilise des purges roulantes qui mettent à jour les pages critiques en premier, suivies par la profondeur et la longueur. Les déploiements bleu/vert dissocient la construction de la version et me donnent le temps de réchauffer les caches de manière ciblée.
// Pipeline des actifs
style.[hash].css
app.[hash].js
// HTML fait toujours référence à de nouveaux hashs Je planifie des fenêtres de purge en dehors des heures de pointe et je surveille le taux de hit immédiatement après. J'évite ainsi les pics de charge sur Origin.
Variantes d'images, DPR et Responsive Caching
Je génère des variantes d'images (taille, format) de manière déterministe, afin que la clé de cache reste stable. Pour les variantes WebP/AVIF, je sépare explicitement par le chemin du fichier ou par des paramètres plutôt que par le seul en-tête Accept, afin d'éviter les explosions Vary. Pour les affichages haute résolution (DPR), j'utilise srcset/sizes, ce qui permet au navigateur de choisir la meilleure variante et au cache d'intervenir par asset concret.
<img src="img/hero-1024.jpg"
srcset="img/hero-768.jpg 768w, img/hero-1024.jpg 1024w, img/hero-1600.jpg 1600w"
sizes="(max-width: 768px) 90vw, 1024px" alt=""> Je maintiens le nombre de variantes par motif à un niveau faible et je nettoie les tailles obsolètes du pipeline afin d'éviter la fragmentation du cache.
Planification de la capacité : mémoire cache et taille des objets
Je dimensionne les caches en fonction des modèles d'accès réels : quelques grands objets (images, vidéos) nécessitent d'autres stratégies que de nombreux petits objets (HTML, JSON). Je fixe des limites à la taille maximale des objets et je vérifie si les objets populaires restent en mémoire. Un taux de réutilisation élevé est plus important que la taille absolue ; c'est pourquoi je trie les clés, je fusionne les variantes et j'évite les doublons.
// Exemple : Limites
max_object_size = 10m
default_ttl = 600
nuke_limit = modéré (évictions sans décrochage) Liste de contrôle pratique pour la mise en œuvre
J'active OPcache avec une mémoire suffisante et contrôle le taux de hits. Ensuite, je mets en place la mise en cache des pages, j'exclue les chemins critiques et je précharge les URL importantes. Ensuite, je définis des en-têtes de navigateur avec des durées longues pour les fichiers non modifiables et le versionnement. Dans le CDN, je définis des clés de cache, des TTL et des stratégies de purge et j'active stale-while-revalidate. Pour finir, je vérifie à l'aide d'outils de mesure si le TTFB, le LCP et le Edge-Hit-Rate atteignent les objectifs.
Bref résumé
J'utilise Mise en cache hiérarchique : OPcache accélère le code, le cache de la page fournit le HTML, les en-têtes du navigateur conservent les actifs en local et Edge rapproche le contenu des utilisateurs. Avec des clés claires, des TTL adaptés et une validation intelligente, je réduis la charge du serveur, la bande passante et la latence. Des valeurs de mesure garantissent les progrès et montrent le potentiel d'optimisation. Il en résulte une chaîne fiable de l'origine jusqu'au terminal. Si l'on cherche en plus des détails sur la livraison globale, on trouve dans la pratique suffisamment de points de départ pour rendre sa propre architecture sensiblement plus rapide.


