Cache navigateur, serveur et CDN : trois étages souvent confondus

Les trois niveaux de cache web forment une chaîne complémentaire entre le navigateur, le serveur et le CDN

Un même fichier CSS de 45 Ko peut être chargé zéro, une ou trois fois selon la façon dont le cache est configuré. Quand un visiteur revient sur votre site et que la page met autant de temps à s’afficher qu’à la première visite, c’est souvent parce que le cache navigateur, le cache serveur et le cache CDN ne travaillent pas ensemble. Le problème, c’est que ces trois mécanismes portent le même nom, mais agissent à des endroits complètement différents de la chaîne de chargement. Résultat : on active un plugin de cache en pensant que tout est réglé, alors qu’on n’a traité qu’un seul étage sur trois.

Dans cet article

  • Le cache navigateur stocke les fichiers localement sur le poste du visiteur et évite de retélécharger CSS, JS et images à chaque page
  • Le cache serveur génère des pages HTML statiques côté hébergement, ce qui peut diviser le temps de réponse par 5 à 10
  • Le cache CDN duplique le contenu sur des dizaines de serveurs géographiques pour réduire la latence réseau
  • Un en-tête Cache-Control mal configuré peut annuler tout le bénéfice d’un plugin de cache WordPress
  • Les trois étages sont complémentaires : désactiver l’un d’eux crée un goulet d’étranglement mesurable
  • Le gain cumulé dépasse souvent 70 % de réduction du temps de chargement total

Le principe général du cache en une minute

Le cache est un espace de stockage temporaire qui conserve une copie d’un contenu déjà généré ou déjà téléchargé. Au lieu de refaire le travail depuis zéro, le système vérifie d’abord si une copie valide existe quelque part. Si oui, il la sert directement. Si non, il génère le contenu, le sert, puis en stocke une copie pour la prochaine fois.

Ce mécanisme existe à plusieurs niveaux de la chaîne de chargement d’une page web. Quand vous tapez une URL dans votre navigateur, la requête traverse plusieurs étapes : le navigateur lui-même, éventuellement un réseau de diffusion de contenu (CDN), puis le serveur d’hébergement. À chacune de ces étapes, un cache peut intervenir. C’est précisément cette superposition qui crée la confusion : le mot « cache » désigne trois mécanismes distincts qui fonctionnent à des endroits différents, avec des règles différentes et des méthodes de purge différentes.

Pour bien comprendre la différence entre cache navigateur et cache serveur, il faut d’abord savoir où chacun se situe dans cette chaîne. Le cache navigateur agit avant même que la requête ne quitte l’ordinateur du visiteur. Le cache serveur agit au moment où le serveur reçoit la requête. Et le cache CDN agit entre les deux, sur un serveur intermédiaire géographiquement proche du visiteur.

Cache navigateur : ce qui se passe sur le poste du visiteur

Le cache navigateur est le premier étage. Lorsque vous visitez un site pour la première fois, votre navigateur télécharge l’ensemble des ressources nécessaires : fichiers HTML, feuilles de style CSS, scripts JavaScript, images, polices de caractères. Tous ces fichiers sont stockés localement sur votre disque dur, dans un répertoire géré par Chrome, Firefox, Safari ou Edge.

Lors de votre deuxième visite, le navigateur vérifie si les fichiers stockés localement sont encore valides. Cette vérification repose sur les en-têtes HTTP envoyés par le serveur lors du premier téléchargement. Deux mécanismes principaux entrent en jeu :

  • Cache-Control / max-age : le serveur indique pendant combien de secondes le fichier peut être réutilisé sans aucune vérification. Un max-age=31536000 signifie que le fichier est valide pendant un an.
  • ETag / Last-Modified : si le délai est expiré, le navigateur envoie une requête conditionnelle au serveur pour vérifier si le fichier a changé. Si le serveur répond 304 Not Modified, le navigateur utilise sa copie locale sans retélécharger le fichier.

Le gain est considérable. Sur un site WordPress classique, les ressources statiques représentent souvent 80 à 90 % du poids total de la page. Si le cache navigateur est correctement configuré, un visiteur récurrent ne retélécharge que le HTML (quelques Ko), tandis que les images, CSS et JS sont servis instantanément depuis son propre disque. J’ai mesuré sur plusieurs projets clients des temps de chargement qui passaient de 2,8 secondes à moins de 0,6 seconde à la deuxième visite, uniquement grâce au cache navigateur.

Le revers de la médaille, c’est que le cache navigateur est hors de votre contrôle direct. Vous ne pouvez pas le purger à distance. Si vous modifiez un fichier CSS et que l’ancien est encore en cache chez le visiteur, il verra l’ancienne version. C’est pourquoi les développeurs utilisent le « cache busting » : ajouter un numéro de version ou un hash dans le nom du fichier (style.abc123.css) pour forcer le navigateur à télécharger la nouvelle version.

Cache serveur : éviter de recalculer chaque page

Le cache serveur agit à l’autre bout de la chaîne, directement sur la machine qui héberge votre site. Son rôle est de stocker le résultat d’un traitement pour ne pas avoir à le refaire à chaque requête.

Prenons l’exemple d’une page WordPress. Sans cache serveur, chaque visite déclenche la séquence suivante : PHP interprète le code du thème, interroge la base de données MySQL pour récupérer le contenu, assemble le HTML, puis l’envoie au navigateur. Cette opération peut prendre 200 à 800 millisecondes sur un hébergement mutualisé. Avec un cache serveur, la page HTML générée est stockée en mémoire ou sur disque. La requête suivante reçoit directement ce fichier HTML statique, en 20 à 50 millisecondes. PHP et MySQL ne sont même pas sollicités.

Plusieurs types de cache serveur coexistent :

  • Cache de page complète (full-page cache) : stocke la page HTML entière. C’est ce que font les plugins comme WP Super Cache ou W3 Total Cache sur WordPress, ou les reverse proxies comme Varnish.
  • Cache d’opcode (OPcache) : stocke le bytecode PHP compilé pour éviter de recompiler les fichiers à chaque requête. C’est un cache au niveau du langage, transparent pour l’utilisateur. Mettre à jour votre version de PHP améliore d’ailleurs les performances d’OPcache.
  • Cache d’objets (Redis, Memcached) : stocke les résultats de requêtes SQL fréquentes en mémoire vive. Utile pour les sites dynamiques avec beaucoup de requêtes répétitives, comme les boutiques WooCommerce.
  • Cache de base de données : MySQL dispose de son propre cache de requêtes, bien que celui-ci ait été retiré à partir de MySQL 8.0 au profit de solutions externes comme Redis.

Le cache serveur est particulièrement efficace sur les hébergements mutualisés où les ressources CPU sont partagées. Un site qui reçoit 500 visites par heure sans cache serveur consomme 500 exécutions PHP. Avec un cache de page, il n’en consomme qu’une seule (celle qui génère le cache), les 499 autres étant servies directement depuis le fichier statique.

La purge du cache serveur est, contrairement au cache navigateur, entièrement sous votre contrôle. Vous pouvez le vider depuis le tableau de bord WordPress, via un plugin, en ligne de commande ou automatiquement à chaque publication d’article.

Cache CDN : rapprocher le contenu du visiteur

Le cache CDN constitue le troisième étage. Un CDN (Content Delivery Network) est un réseau de serveurs répartis géographiquement. Quand un visiteur demande une page, le CDN la sert depuis le serveur le plus proche de lui, appelé « edge server » ou point de présence (PoP).

Le principe est simple : si votre serveur est hébergé à Paris et qu’un visiteur se connecte depuis Marseille, la requête parcourt environ 800 km aller-retour. Avec un CDN disposant d’un PoP à Lyon, cette distance tombe à 300 km. Le gain en latence réseau est de l’ordre de 30 à 60 millisecondes par requête. Sur une page qui charge 40 ressources, le cumul devient significatif.

Les CDN les plus utilisés en France sont Cloudflare (gratuit en offre de base), KeyCDN, Bunny CDN et le CDN intégré de certains hébergeurs. Leur fonctionnement repose sur un mécanisme de cache similaire à celui du serveur :

  • Le CDN reçoit la première requête, la transmet au serveur d’origine (votre hébergement), récupère la réponse et la stocke sur son edge server.
  • Les requêtes suivantes pour le même contenu sont servies directement par l’edge server, sans contacter votre hébergement.
  • La durée de mise en cache est contrôlée par les en-têtes HTTP Cache-Control et s-maxage, ou par la configuration du CDN.

Le cache CDN est particulièrement utile pour les ressources statiques lourdes : images, vidéos, fichiers CSS et JavaScript. Il est moins pertinent pour le HTML des pages dynamiques, sauf si le site a peu de personnalisation (pas de contenu connecté, pas de panier e-commerce visible).

Un point important : le CDN n’accélère pas le traitement côté serveur. Si votre page met 800 ms à être générée par PHP, le CDN ne change rien à ce délai lors du premier chargement. Il ne fait que stocker et redistribuer le résultat. C’est pourquoi le cache serveur et le cache CDN sont complémentaires, pas interchangeables.

Tableau comparatif des trois caches

Pour visualiser clairement la différence entre cache navigateur, serveur et CDN, voici un tableau qui résume leurs caractéristiques respectives.

Caractéristique Cache navigateur Cache serveur Cache CDN
Emplacement Poste du visiteur Serveur d’hébergement Edge servers répartis
Contrôlé par En-têtes HTTP + navigateur Plugin, Varnish, OPcache Configuration CDN + en-têtes
Contenu mis en cache CSS, JS, images, polices Pages HTML, requêtes SQL, bytecode Ressources statiques, parfois HTML
Gain principal Supprime le téléchargement Supprime le calcul PHP/SQL Réduit la latence réseau
Purge possible ? Non (côté visiteur) Oui (admin serveur) Oui (tableau de bord CDN)
Bénéficiaires Visiteurs récurrents Tous les visiteurs Visiteurs éloignés du serveur
Temps de réponse typique 0 ms (lecture locale) 20 à 50 ms 30 à 80 ms
Complexité de mise en place Faible (en-têtes .htaccess) Moyenne (plugin ou config serveur) Moyenne (DNS + paramétrage)

Ce tableau montre bien que chaque étage résout un problème différent. Installer un plugin de cache sur WordPress ne règle que le deuxième étage. Si les en-têtes Cache-Control ne sont pas configurés, le navigateur retéléchargera les ressources à chaque visite. Et sans CDN, un visiteur distant subira toujours la latence réseau, même si le serveur répond en 20 ms. Pour diagnostiquer quel étage pose problème, je recommande de commencer par identifier les vraies causes de lenteur avant d’empiler les solutions.

Configuration pratique : les en-têtes HTTP qui comptent

La plupart des caches web reposent sur les en-têtes HTTP. Ce sont des métadonnées invisibles pour le visiteur, envoyées avec chaque réponse du serveur. Voici les en-têtes essentiels à connaître et à configurer.

Cache-Control

C’est l’en-tête le plus important. Il indique à la fois au navigateur et au CDN comment traiter la ressource. Les directives les plus courantes sont :

  • public : la réponse peut être mise en cache par n’importe quel intermédiaire (navigateur, CDN, proxy).
  • private : seul le navigateur peut mettre en cache (utilisé pour les pages avec contenu personnalisé).
  • max-age=X : durée de validité en secondes pour le navigateur.
  • s-maxage=X : durée de validité spécifique aux caches partagés (CDN, proxy). Prioritaire sur max-age pour ces caches.
  • no-cache : le fichier peut être stocké, mais doit être revalidé auprès du serveur avant chaque utilisation.
  • no-store : aucun stockage autorisé, nulle part. À réserver aux données sensibles.

Sur un site WordPress, la configuration typique via .htaccess sur Apache ressemble à ceci :

# Cache navigateur pour les ressources statiques
<IfModule mod_expires.c>
  ExpiresActive On
  ExpiresByType image/jpeg "access plus 1 year"
  ExpiresByType image/png "access plus 1 year"
  ExpiresByType text/css "access plus 1 month"
  ExpiresByType application/javascript "access plus 1 month"
</IfModule>

Sur Nginx, l’équivalent se configure dans le bloc server :

location ~* \.(css|js|jpg|png|gif|ico|woff2)$ {
    expires 30d;
    add_header Cache-Control "public, no-transform";
}

ETag et Last-Modified

Ces en-têtes servent à la revalidation. Quand le max-age est expiré, le navigateur envoie une requête conditionnelle avec l’ETag ou la date de dernière modification. Si le fichier n’a pas changé, le serveur répond 304 Not Modified sans renvoyer le contenu. Cela économise la bande passante tout en garantissant que le visiteur voit la dernière version. L’économie de bande passante peut être significative sur les hébergements avec des quotas.

Vary

L’en-tête Vary indique aux caches que la réponse change en fonction de certains paramètres. Par exemple, Vary: Accept-Encoding signifie que la version compressée (gzip) et la version non compressée sont des réponses différentes. Mal configuré, cet en-tête peut réduire considérablement l’efficacité du CDN en multipliant les variantes stockées.

Les erreurs fréquentes qui annulent le cache

Après avoir accompagné des dizaines de projets sur ces questions de performance, j’ai identifié des erreurs récurrentes qui réduisent à néant les bénéfices du cache.

Erreur 1 : ne configurer que le cache serveur

C’est le scénario le plus courant. On installe un plugin de cache WordPress, on voit le temps de réponse serveur passer de 600 ms à 80 ms et on pense que le travail est terminé. Mais si les en-têtes Cache-Control pour les fichiers statiques ne sont pas configurés, le navigateur retélécharge chaque image et chaque fichier CSS à chaque page vue. Le gain côté serveur est annulé par le temps de transfert réseau.

Erreur 2 : mettre no-cache sur tout

Par excès de prudence, certains développeurs ajoutent no-cache ou no-store sur l’ensemble des ressources. Le site fonctionne, mais il est systématiquement plus lent qu’il ne devrait l’être. Ces directives doivent être réservées aux pages dynamiques personnalisées (panier e-commerce, tableau de bord utilisateur) et aux données sensibles.

Erreur 3 : oublier le cache busting

Configurer un max-age d’un an sur les fichiers CSS, c’est bien. Mais si le nom du fichier ne change pas quand on modifie le code, les visiteurs récurrents verront l’ancien design pendant des semaines voire des mois. WordPress gère normalement le versioning via le paramètre ?ver=, mais certains plugins de minification suppriment ce paramètre, ce qui provoque des incohérences visuelles.

Erreur 4 : purger le CDN mais pas le cache serveur

Quand on met à jour le contenu, il faut purger les caches dans le bon ordre : d’abord le cache serveur (pour que la nouvelle version soit générée), puis le cache CDN (pour que les edge servers récupèrent cette nouvelle version). Purger le CDN en premier ne sert à rien : il ira chercher la nouvelle version auprès du serveur, qui lui servira encore l’ancienne depuis son propre cache.

Erreur 5 : ignorer le cache sur les pages de connexion

Mettre en cache la page de connexion WordPress ou la page « mon compte » WooCommerce peut exposer des données personnelles d’un visiteur à un autre. Les plugins de cache sérieux excluent automatiquement ces URL, mais une configuration manuelle via Varnish ou Nginx nécessite de définir explicitement les exclusions.

Stratégie combinée : faire travailler les trois étages ensemble

L’objectif est d’obtenir le meilleur temps de chargement en activant les trois couches de cache de façon cohérente. Voici une stratégie qui fonctionne pour la majorité des sites vitrine et blogs sous WordPress, et qui s’adapte facilement à d’autres CMS.

Étape 1 : configurer le cache navigateur via les en-têtes

Dans le fichier .htaccess ou la configuration Nginx, définissez des durées de cache adaptées au type de fichier :

  • Images (JPEG, PNG, WebP, SVG) : 1 an. Ces fichiers changent rarement une fois publiés.
  • CSS et JavaScript : 1 mois, avec cache busting (hash dans le nom du fichier).
  • Polices (WOFF2) : 1 an. Elles ne changent quasiment jamais.
  • HTML : no-cache pour forcer la revalidation à chaque visite, ce qui garantit que le visiteur voit toujours la dernière version du contenu.

Étape 2 : activer le cache serveur

Sur WordPress, un plugin de cache de page suffit pour la plupart des sites. Si votre hébergeur propose Varnish ou LiteSpeed Cache, activez-le en priorité : ces solutions sont plus performantes qu’un plugin PHP car elles interceptent la requête avant même que PHP ne démarre. Activez également OPcache (généralement activé par défaut sur les hébergements récents) et, si disponible, un cache d’objets Redis.

Étape 3 : ajouter un CDN

Pour un site français avec un public principalement hexagonal, le bénéfice d’un CDN est réel mais modéré. Si votre serveur est hébergé en France, la latence vers les visiteurs français est déjà faible. En revanche, si vous visez un public européen ou international, le CDN devient indispensable. Cloudflare en offre gratuite constitue un bon point de départ. Selon la documentation officielle de Mozilla sur la mise en cache HTTP, les bonnes pratiques de configuration des en-têtes s’appliquent de la même façon que vous utilisiez un CDN ou non.

Étape 4 : vérifier et mesurer

Utilisez l’onglet « Réseau » des outils de développement de votre navigateur (F12) pour vérifier les en-têtes de chaque ressource. Cherchez les colonnes Status (200 vs 304 vs « from cache »), Size (taille transférée vs « cached ») et Time. Un fichier correctement mis en cache côté navigateur affiche « (disk cache) » ou « (memory cache) » dans la colonne Size, avec un temps de chargement de 0 ms.

Pour le cache serveur, vérifiez l’en-tête de réponse X-Cache ou X-Cache-Status. Un HIT signifie que le cache a répondu. Un MISS signifie que la page a été générée dynamiquement. Si toutes vos pages affichent MISS, votre cache serveur ne fonctionne pas correctement. Les raisons courantes incluent un cookie qui empêche la mise en cache ou une règle d’exclusion trop large. Si vous envisagez de changer d’hébergeur, vérifiez les solutions de cache proposées avant de migrer.

À retenir

  • Configurez les en-têtes Cache-Control avec des durées adaptées par type de fichier (images : 1 an, CSS/JS : 1 mois)
  • Activez un cache de page serveur avant d’ajouter un CDN : le gain est souvent supérieur
  • Utilisez le cache busting (hash dans les noms de fichiers) pour éviter les problèmes de versions obsolètes
  • Purgez toujours dans l’ordre serveur puis CDN lors des mises à jour de contenu
  • Vérifiez les en-têtes dans l’onglet Réseau de votre navigateur : un X-Cache: HIT confirme que le cache fonctionne

Questions fréquentes


Quelle est la différence entre un serveur et un navigateur ?

Le navigateur est le logiciel installé sur votre ordinateur ou smartphone (Chrome, Firefox, Safari) qui affiche les pages web. Le serveur est une machine distante qui stocke les fichiers du site et les envoie au navigateur quand celui-ci les demande. Le navigateur est côté client, le serveur est côté hébergement. Le cache navigateur stocke des copies locales des fichiers pour éviter de les retélécharger. Le cache serveur stocke des pages pré-générées pour éviter de les recalculer.


C’est quoi un cache navigateur ?

Le cache navigateur est un espace de stockage temporaire sur votre ordinateur où le navigateur conserve les fichiers déjà téléchargés : images, feuilles de style CSS, scripts JavaScript, polices. Quand vous revisitez un site, le navigateur charge ces fichiers depuis votre disque dur au lieu de les retélécharger, ce qui accélère considérablement l’affichage. La durée de conservation est définie par les en-têtes HTTP Cache-Control envoyés par le serveur.


Qu’est-ce qu’un serveur de cache ?

Un serveur de cache est un logiciel ou un équipement qui stocke des copies de contenus fréquemment demandés pour les servir plus rapidement. Varnish est l’exemple le plus connu dans le monde du web : il se place devant le serveur web (Apache ou Nginx) et intercepte les requêtes. Si la page demandée est en cache, Varnish la sert directement en quelques millisecondes, sans solliciter PHP ni la base de données. Redis et Memcached sont d’autres exemples de caches serveur spécialisés dans le stockage en mémoire vive.


Le cache est-il côté client ou côté serveur ?

Les deux. Le cache côté client (cache navigateur) stocke les ressources statiques sur le poste du visiteur. Le cache côté serveur stocke les pages HTML générées ou les résultats de requêtes SQL sur le serveur d’hébergement. Un troisième type, le cache CDN, se situe entre les deux, sur des serveurs intermédiaires répartis géographiquement. Ces trois niveaux sont complémentaires et servent des objectifs différents : le client évite le téléchargement, le serveur évite le calcul, le CDN réduit la latence réseau.


Faut-il vider le cache navigateur régulièrement ?

Pour un utilisateur ordinaire, vider le cache navigateur n’est nécessaire que si un site affiche un contenu obsolète ou des erreurs visuelles. Le navigateur gère automatiquement l’espace disque en supprimant les fichiers les plus anciens quand l’espace alloué est plein. Pour un développeur qui modifie fréquemment le code d’un site, le raccourci Ctrl+Shift+R (ou Cmd+Shift+R sur Mac) permet de forcer un rechargement complet sans vider tout le cache.


Un CDN remplace-t-il le cache serveur ?

Non, le CDN ne remplace pas le cache serveur. Le CDN stocke et redistribue le contenu depuis des serveurs géographiquement proches du visiteur, ce qui réduit la latence réseau. Mais il ne modifie pas le temps de génération de la page côté serveur. Si votre page met 800 ms à être construite par PHP, le CDN ne changera rien à ce délai pour le premier visiteur. Le cache serveur, lui, élimine cette phase de calcul. Les deux solutions se complètent : le cache serveur accélère la génération, le CDN accélère la distribution.


Damien Roux
Damien Roux

Ingénieur système et expert hébergement web. Fondateur de web-city.fr, il partage guides pratiques, comparatifs objectifs et outils gratuits pour choisir le bon hébergeur et créer son site WordPress.

Scroll to Top