Cache HTTP : le guide pratique pour diviser vos temps de réponse
Cache-Control, ETag, stale-while-revalidate : comment fonctionne le cache HTTP, quelles règles poser selon le type de contenu, et les pièges qui invalident tout.
Le cache est le levier de performance le plus puissant du web : servir une réponse déjà calculée coûte des microsecondes là où la générer coûte des dizaines ou centaines de millisecondes. C'est aussi un sujet où une règle mal posée fait perdre des heures — un client qui voit une page périmée, un déploiement qui ne « prend » pas. Ce guide pose les règles par type de contenu, avec les pièges connus.
Les trois familles de contenu
Tout part d'une question : cette réponse peut-elle être réutilisée, par qui, et combien de temps ?
Les assets fingerprintés (fichiers dont le nom change avec le contenu :
app.4f8a2c.js, logo.d41d8c.svg) peuvent être cachés indéfiniment : si
le contenu change, l'URL change. C'est le cas idéal :
Cache-Control: public, max-age=31536000, immutable
Les pages HTML publiques (accueil, articles, fiches produit) changent
parfois, mais pas à chaque seconde. Les servir depuis un cache avec une
courte durée de vie absorbe les pics de trafic sans sacrifier la
fraîcheur. Le pattern stale-while-revalidate est précieux : le cache
sert immédiatement la version qu'il a, et la rafraîchit en arrière-plan.
Cache-Control: public, max-age=60, stale-while-revalidate=600
Les réponses personnalisées (panier, compte, tableau de bord) ne doivent jamais être partagées entre utilisateurs :
Cache-Control: private, no-store
Le piège classique de cette famille : une page publique qui embarque un fragment personnalisé (« Bonjour Kevin »). Soit la page devient privée — et le cache partagé est perdu — soit le fragment personnalisé est chargé séparément côté client, et la page reste cachable. Ce choix d'architecture se fait à la conception, pas après coup.
ETag et revalidation : le cache « gratuit »
Même sans durée de vie, un serveur peut éviter de renvoyer un contenu
inchangé. Il émet un identifiant de version (ETag) ; le navigateur le
présente à la visite suivante (If-None-Match) ; si rien n'a changé, la
réponse est un 304 Not Modified sans corps. On économise la bande
passante et le rendu, pas le calcul serveur — c'est un complément, pas un
substitut au Cache-Control.
Où placer le cache ?
Il existe quatre étages, cumulables :
| Étage | Ce qu'il absorbe | Limite |
|---|---|---|
| Navigateur | Les visites répétées du même visiteur | Ne protège pas le serveur du trafic nouveau |
| Reverse proxy (Caddy, Nginx, Varnish) | L'essentiel du trafic public | À opérer soi-même |
| CDN | Trafic mondial, pics, DDoS de base | Coût, invalidation parfois lente, dépendance |
| Applicatif (Redis, mémoire) | Les calculs coûteux derrière les pages | Ne réduit pas le coût du rendu complet |
Il n'y a pas de « bon » étage universel. Un site vitrine français servi depuis un VPS bien configuré avec un reverse proxy qui cache n'a pas toujours besoin d'un CDN ; une audience internationale ou des pics imprévisibles le justifient davantage. L'important est de commencer par les en-têtes : tous les étages en aval les respectent.
Les pièges qui coûtent cher
no-cachene veut pas dire « pas de cache » : il signifie « revalider avant de servir ». C'estno-storequi interdit le stockage. Beaucoup de configurations utilisent l'un pour l'autre.- Cacher une réponse avec
Set-Cookie: un cache partagé mal réglé peut servir le cookie de session d'un utilisateur à un autre. Les reverse proxies sérieux refusent par défaut — ne désactivez pas cette protection. - Oublier
Vary: si la réponse dépend d'un en-tête (langue, compression), il faut le déclarer (Vary: Accept-Encoding), sinon le cache sert la mauvaise variante. - Des durées héroïques sans fingerprinting :
max-age=31536000sur unstyle.cssnon versionné, et votre prochaine mise en production mettra un an à atteindre certains visiteurs.
Ce qu'il faut retenir
Le cache HTTP se décide contenu par contenu : indéfini pour les assets
fingerprintés, court et stale-while-revalidate pour les pages publiques,
no-store pour le personnalisé. Posez les en-têtes d'abord — ils sont
compris par tous les étages —, ajoutez les étages ensuite, selon votre
trafic réel. Et testez le résultat : un curl -I sur vos cinq URLs les
plus visitées révèle en général au moins une règle absente ou incohérente.
Deux articles voisins.
Vous avez le même problème ?
C'est souvent comme ça que les missions commencent. Décrivez votre contexte, on vous dit ce qu'on en pense sous 24 h.
Décrire votre projet