6 juillet 2026

Pourquoi un cache Web change votre façon de développer

Comment concevoir WordPress et WooCommerce pour qu'ils fonctionnent correctement derrière Varnish ou d'autres caches web, en évitant les contournements, les cookies inutiles et le contenu dynamique mal géré côté application.

Table des matières de l'article :

Lorsqu'un site WordPress ou WooCommerce voit son trafic, sa complexité et le nombre de requêtes simultanées augmenter, il arrive inévitablement un moment où la simple « optimisation PHP » ne suffit plus. Certes, il est possible d'améliorer les requêtes SQL, de réduire le nombre de plugins inutiles, d'utiliser le cache d'objets, de mettre à jour PHP-FPM, de configurer OPcache et d'alléger le thème. Autant de mesures utiles, bien sûr. Mais si chaque visite génère une nouvelle exécution de WordPress — avec le démarrage du noyau, le chargement des plugins, les requêtes de base de données, le rendu du thème et la génération du code HTML —, la limitation architecturale persiste.

Le cache web a été créé précisément pour résoudre ce problème : éviter que le serveur de l’application ne génère la même réponse lorsqu’elle est identique pour de nombreux utilisateurs. Autrement dit, si la page d’accueil publique d’un site est identique pour des milliers de visiteurs anonymes, il est inutile d’exécuter du code PHP et d’interroger MySQL des milliers de fois. Il est bien plus efficace de générer cette page une seule fois, de la mettre en cache et de la servir directement depuis le cache jusqu’à son expiration ou son invalidation.

Cette approche n'est pas un simple artifice, mais un changement de perspective. Les développeurs ne doivent plus se contenter de penser « cette fonction affiche des données », mais se demander : ces données peuvent-elles être partagées entre plusieurs utilisateurs ? Si oui, elles peuvent être intégrées dans du HTML mis en cache. Sinon, il faut les gérer différemment : via JavaScript, des appels AJAX/REST, des inclusions côté serveur (Edge Side Includes), des points de terminaison non mis en cache, des cookies contrôlés ou une logique applicative distincte.

La mise en cache HTTP est l'un des outils les plus puissants pour réduire le TTFB, la charge du processeur, les requêtes de base de données et la saturation du serveur. Cependant, c'est aussi l'un des plus faciles à perturber par une simple ligne de code erronée. Un cookie défini aléatoirement, un en-tête, Cache-Control: no-store Sur une page publique, une session PHP lancée n'importe où, une personnalisation côté serveur par utilisateur ou une variante mobile/de bureau mal gérée peuvent transformer une plateforme performante en un système qui contourne constamment le cache.

Ce guide est destiné aux développeurs travaillant sur WordPress et WooCommerce utilisant Varnish Cache ou un cache web générique, y compris les configurations basées sur un proxy inverse NGINX, un CDN ou un cache HTTP au niveau de l'hébergement.

Qu'est-ce qu'un cache Web ?

Un cache web est un composant intermédiaire qui stocke temporairement une réponse HTTP et la réutilise pour les requêtes compatibles suivantes. Il peut se trouver dans le navigateur de l'utilisateur, dans un CDN, dans un proxy inverse devant le serveur web, ou directement sur le serveur web via des modules tels que… proxy_cache o fastcgi_cache de NGINX.

Dans le contexte de l'hébergement et des systèmes, lorsqu'on parle de cache web, on fait souvent référence à un cache partagé côté serveur , c'est-à-dire un cache utilisé par plusieurs utilisateurs et placé en amont de l'application. Le flux typique est le suivant :

  • le navigateur demande une page ;
  • la requête atteint le cache ;
  • si le cache possède une copie valide de la réponse, il la sert immédiatement ;
  • si elle ne la possède pas ou si la copie a expiré, transmettez la requête au serveur principal ;
  • Le serveur génère la réponse et le cache décide s'il faut la conserver.

Dans une configuration classique avec Varnish, le chemin peut être :

Browser → Varnish → NGINX/Apache → PHP-FPM → WordPress → MySQL

En cas de correspondance avec le cache, le chemin s'arrête cependant beaucoup plus tôt :

Browser → Varnish → risposta HTML già pronta

Cette différence est considérable. Une réponse fournie par Varnish peut complètement contourner l'exécution PHP, le chargement de WordPress et la connexion à la base de données. Par conséquent, sur les pages publiques à fort trafic, un cache HTTP bien configuré peut faire toute la différence entre un site stable et un site qui plante sous la charge.

Pourquoi Varnish Cache est un choix pour les entreprises

Varnish Cache est l'un des proxys inverses HTTP les plus utilisés pour la diffusion de contenu mis en cache avec des performances élevées et une logique de contrôle très précise. Sa force réside non seulement dans sa rapidité, mais aussi dans sa capacité à décrire le comportement du cache via VCL, son langage de configuration.

Avec Varnish, vous pouvez décider, par exemple, quelles URL ne doivent jamais être mises en cache, quels cookies doivent être ignorés, quels en-têtes doivent être mis en cache, combien de temps une réponse peut rester valide, quand servir du contenu obsolète, comment gérer une purge et comment différencier les variantes de bureau/mobile, la langue, la devise ou le pays.

En entreprise, cette programmabilité est essentielle. Un site WooCommerce n'a pas les mêmes besoins qu'un magazine, un portail de publication n'est pas soumis aux mêmes règles qu'une plateforme d'adhésion, et une page de destination publicitaire n'offre pas le même dynamisme qu'un espace client. Un cache efficace ne peut pas être un simple interrupteur : il doit constituer une politique applicative cohérente.

Varnish est particulièrement adapté lorsque vous souhaitez dissocier la diffusion de contenu public de la génération de contenu dynamique. Le backend WordPress reste responsable de la production de contenu, tandis que Varnish assure une distribution rapide, stable et contrôlable.

Le contrat entre l'application et le cache

Le cache web ne doit pas être perçu comme un élément externe et mystérieux. Il doit être considéré comme faisant partie intégrante de l'architecture de l'application. Le serveur communique avec le cache via des URL, des méthodes HTTP, des en-têtes, des cookies et des codes d'état. Le cache, quant à lui, détermine si une réponse peut être stockée, pendant combien de temps et pour quelles requêtes elle peut être réutilisée.

Pour un développeur, le concept clé est le suivant : chaque page doit clairement indiquer si elle est publique, privée, partageable, variable ou non mise en cache.

Une page publique, comme un article de blog ou une catégorie de produits sans personnalisation par l'utilisateur, peut utiliser des en-têtes similaires :

Cache-Control: public, s-maxage=3600, max-age=300

Cela signifie que le cache partagé peut conserver la page pendant une heure, tandis que le navigateur ne peut la conserver que pendant cinq minutes. À l'inverse, une page privée, comme la page de paiement, l'espace client ou un tableau de bord personnel, doit clairement indiquer qu'elle n'est pas adaptée à la mise en cache partagée.

Cache-Control: private, no-store

Le problème survient lorsque l'application ne fait pas la distinction. Si toutes les pages envoient des cookies, si toutes les sessions ouvrent, si toutes contiennent des données personnelles, le cache ne peut plus faire la différence entre le public et le privé. Dès lors, pour des raisons de sécurité, il aura tendance à ignorer ou à ne rien stocker.

Que se passe-t-il pour le code PHP sur une page mise en cache ?

L'une des erreurs les plus fréquentes lors du développement WordPress avec Varnish est de croire que le code PHP sera exécuté à chaque visite. Ce n'est pas le cas. Si une page est servie depuis le cache, le PHP n'est pas exécuté . Le visiteur reçoit le code HTML généré précédemment.

Cela signifie que toute logique PHP insérée dans le modèle, le thème ou le shortcode est « enregistrée » lors de la génération de la page. Si le premier visiteur anonyme génère une page avec un certain résultat, ce résultat peut également être servi aux visiteurs suivants jusqu'à expiration ou suppression.

C'est idéal pour les contenus publics comme les titres, les textes, les images, les prix standards des produits, les descriptions, le fil d'Ariane, le balisage de schéma, les menus statiques ou les blocs éditoriaux. En revanche, c'est risqué pour tout élément qui varie en fonction de l'utilisateur, de la session, de la géolocalisation, du panier, de la connexion, des préférences personnelles ou de l'historique de navigation.

Mauvais exemple dans un thème WordPress :

<?php
if ( is_user_logged_in() ) {
    echo 'Ciao ' . esc_html( wp_get_current_user()->display_name );
} else {
    echo 'Accedi al tuo account';
}
?>

Si ce code est imprimé sur une page pouvant être mise en cache, une situation ambiguë se produit. Soit le cache est ignoré pour tous les utilisateurs disposant de cookies de connexion, ce qui réduit l'efficacité du système, soit une version incorrecte de la page est enregistrée. Le problème ne vient pas de la fonction elle-même. is_user_logged_in() en soi, mais le fait qu'il soit utilisé pour produire du HTML personnalisé dans une réponse qui devrait être publique.

La solution appropriée consiste à séparer le code HTML public de la personnalisation privée. Le modèle peut imprimer un conteneur neutre :

<div id="user-area" data-endpoint="/wp-json/ms/v1/user-bar">
    <a href="/my-account/">Accedi al tuo account</a>
</div>

JavaScript peut alors interroger un point de terminaison non mis en cache ou mis en cache de manière privée et mettre à jour uniquement ce fragment :

fetch('/wp-json/ms/v1/user-bar', {
credentials: 'same-origin',
headers: {
'Accept': 'application/json'
}
})
.then(response => response.ok ? response.json() : null)
.then(data => {
if (!data || !data.logged_in) return;

```
const box = document.getElementById('user-area');
if (box) {
    box.innerHTML = '<a href="/my-account/">Ciao ' + data.name + '</a>';
}
```

});

De cette manière, la page principale reste mise en cache, tandis que les informations personnelles ne sont chargées séparément qu'en cas de besoin.

La règle d'or : ne placez pas de données privées dans du HTML mis en cache.

En présence de cache Web, la règle la plus importante est simple : tout ce qui est différent pour un utilisateur donné ne doit pas être généré côté serveur dans une page publique mise en cache.

Ceci comprend:

  • nom de l'utilisateur connecté ;
  • nombre de produits dans le panier ;
  • des prix personnalisés pour les groupes de clients ;
  • remises individuelles ;
  • messages basés sur la session ;
  • liste de souhaits personnelle ;
  • Produits récemment consultés ;
  • notifications privées ;
  • contenu basé sur des cookies non normalisés ;
  • contenu basé sur une adresse IP ou une géolocalisation IP non contrôlée.

La mise en cache est optimale lorsque le code HTML est public, déterministe et partageable. Si une page publique contient cinq petits éléments dynamiques, cela ne signifie pas qu'il faille renoncer à la mise en cache de la page entière. Cela signifie simplement qu'il faut concevoir ces cinq éléments comme des fragments dynamiques distincts.

Cookies : la raison la plus courante du contournement du cache

Les cookies constituent probablement le principal point de friction entre le développement d'applications et la mise en cache HTTP. De nombreux frameworks, CMS, plugins marketing, systèmes de suivi, bannières de confidentialité, tests A/B et composants e-commerce déposent des cookies même lorsqu'ils ne sont pas nécessaires. Du point de vue de la mise en cache, la présence d'un cookie dans la requête peut toutefois signifier : « Attention, cette réponse peut être personnalisée. »

Dans Varnish, une configuration prudente tend à ne pas mettre en cache ni à servir les requêtes mises en cache contenant des cookies pertinents. Ce comportement est logique : si le cookie contient une session utilisateur, un panier d’achat ou un jeton d’authentification, l’affichage d’une page partagée peut s’avérer impossible. Le problème est que les cookies présents dans la requête n’ont souvent aucun impact sur le contenu HTML.

Exemples de cookies qui, normalement, ne devraient pas invalider le cache de la page publique :

  • cookies analytiques ;
  • cookies publicitaires ;
  • Les cookies de consentement sont déjà gérés côté navigateur ;
  • cookies de préférences graphiques non utilisés par le serveur ;
  • Cookies de campagne UTM enregistrés uniquement à des fins de suivi ;
  • Cookies techniques non liés au rendu HTML.

Exemples de cookies pouvant nécessiter un contournement ou une modification :

  • wordpress_logged_in_*;
  • wp_woocommerce_session_*;
  • woocommerce_items_in_cart;
  • woocommerce_cart_hash;
  • cookies d'adhésion ;
  • cookie de devise si le prix change côté serveur ;
  • cookie de langue si la langue n'est pas déjà présente dans l'URL ;
  • Cookie de groupe de prix ou de liste de prix client.

Les développeurs doivent donc éviter d'utiliser les cookies comme un simple répertoire d'informations. Chaque cookie doit avoir une finalité précise : le serveur en a-t-il réellement besoin pour générer un code HTML différent ? Dans le cas contraire, il est probablement préférable de ne pas l'inclure dans la décision de mise en cache.

Comment mal utiliser les cookies dans WordPress et WooCommerce

Une erreur fréquente consiste à définir un cookie PHP sur toutes les pages du site, par exemple dans le fichier functions.php, dans un plugin personnalisé ou dans un mu-plugin :

add_action('init', function () {
setcookie('visited_site', '1', time() + 3600, COOKIEPATH, COOKIE_DOMAIN);
});

Ce code semble inoffensif, mais il indique au cache que chaque réponse peut définir un cookie. Si le serveur renvoie un en-tête Set-CookieDe nombreuses configurations ne stockent pas la réponse afin d'éviter le partage des cookies entre utilisateurs. Par conséquent, même des pages parfaitement publiques peuvent devenir impossibles à mettre en cache.

Une autre erreur courante :

add_action('init', function () {
if (!session_id()) {
session_start();
}
});

Démarrer une session PHP sur WordPress est presque toujours une mauvaise idée lorsque la mise en cache de la page entière est activée. La session introduit un état individuel, définit des cookies et rend la page moins facile à partager. Dans la plupart des cas, elle sert uniquement à afficher un message, à enregistrer une préférence temporaire ou à mémoriser une valeur qui pourrait être gérée avec JavaScript, le stockage local, les données transitoires côté serveur ou un point de terminaison dédié.

Dans WooCommerce, les cookies de panier sont nécessaires, mais ne doivent pas servir à contourner les restrictions de confidentialité à l'échelle du site. Une configuration correcte exclut les actions liées à la validation de la commande, au panier, à mon compte et au contenu du panier, tout en autorisant la mise en cache des pages produits, des catégories et des pages éditoriales lorsqu'aucun paramètre de confidentialité n'est appliqué.

WooCommerce : Ce qui doit rester dynamique

WooCommerce impose des exigences particulières car un site e-commerce comporte à la fois des pages publiques et des pages hautement privées. La page produit est généralement publique. En revanche, le panier, la page de paiement et l'espace client sont privés et doivent être exclus du cache de la page complète.

Les pages qui ne devraient normalement pas être mises en cache sont :

  • Panier, car il affiche un contenu lié à la session du client ;
  • Paiement, car il contient des données, des méthodes d'expédition, des informations de paiement, un nonce et l'état de la commande ;
  • Mon compte, car il s'agit d'un espace privé ;
  • Point de terminaison WooCommerce, comme vous l'appelez wc-ajax ou des API opérationnelles ;
  • URL avec des actions comme ?add-to-cart=, coupons, suppression de produits et mise à jour des quantités.

Au contraire, ils peuvent souvent être mis en cache :

  • page d'accueil publique ;
  • pages de catégories de produits ;
  • fiches produits pour utilisateurs anonymes ;
  • articles de blog ;
  • page d'accueil ;
  • Pages CMS statiques ;
  • Ressources statiques et images.

Attention toutefois aux prix, aux stocks et aux promotions. Si le prix varie selon l'utilisateur, le pays, la devise, le rôle, la quantité ou une liste de prix B2B, la page produit n'est plus une simple page publique. Il vous faut alors choisir entre une gestion différenciée du cache, le chargement du prix via JavaScript, l'utilisation de points de terminaison dédiés ou l'exclusion du cache des seules conditions réellement dynamiques.

Exemple de VCL pour WordPress et WooCommerce

Un véritable VCL doit toujours être adapté à l'infrastructure, à la version de Varnish, à la configuration des en-têtes et aux besoins du site. Cet exemple illustre toutefois le principe général : transmettre les zones réellement dynamiques, supprimer les cookies inutiles et laisser les pages publiques accessibles en cache.

sub vcl_recv {
# Non cacheare metodi non sicuri o non idempotenti
if (req.method != "GET" && req.method != "HEAD") {
return (pass);
}

```
# WordPress admin e login sempre pass
if (req.url ~ "^/wp-admin" || req.url ~ "^/wp-login.php") {
    return (pass);
}

# WooCommerce: aree dinamiche
if (req.url ~ "^/(cart|checkout|my-account)(/|$)") {
    return (pass);
}

# WooCommerce: azioni e AJAX operativi
if (req.url ~ "(\?add-to-cart=|wc-ajax=|remove_item=|apply_coupon=)") {
    return (pass);
}

# Utenti WordPress loggati: pass
if (req.http.Cookie ~ "wordpress_logged_in_") {
    return (pass);
}

# Carrello WooCommerce presente: pass o gestione dedicata
if (req.http.Cookie ~ "woocommerce_items_in_cart=1") {
    return (pass);
}

# Rimuovi cookie che non influenzano l'HTML pubblico
if (req.http.Cookie) {
    set req.http.Cookie = regsuball(req.http.Cookie, "(^|; )_ga=[^;]*", "");
    set req.http.Cookie = regsuball(req.http.Cookie, "(^|; )_gid=[^;]*", "");
    set req.http.Cookie = regsuball(req.http.Cookie, "(^|; )_fbp=[^;]*", "");
    set req.http.Cookie = regsuball(req.http.Cookie, "(^|; )cookie_notice_accepted=[^;]*", "");

    # Se dopo la pulizia il cookie è vuoto, rimuovilo
    if (req.http.Cookie ~ "^\s*$") {
        unset req.http.Cookie;
    }
}
```

}

sub vcl_backend_response {
# Non cacheare risposte che impostano cookie su aree dinamiche
if (bereq.url ~ "^/(cart|checkout|my-account)(/|$)") {
set beresp.uncacheable = true;
set beresp.ttl = 0s;
return (deliver);
}

```
# Per pagine pubbliche, se il backend imposta cookie inutili, valutarne la rimozione
if (bereq.method == "GET" && bereq.url !~ "^/(wp-admin|wp-login.php|cart|checkout|my-account)") {
    unset beresp.http.Set-Cookie;
}

# TTL di esempio per contenuti pubblici
if (beresp.status == 200) {
    set beresp.ttl = 1h;
    set beresp.grace = 10m;
}
```

}

Ce fichier ne doit pas être copié tel quel en production. Il s'agit d'un cadre conceptuel. Sur un site réel, vous devrez vérifier les cookies, les plugins installés, l'espace membre, la gestion multilingue, les devises, la géolocalisation IP, la purge du cache, les en-têtes du serveur et le processus de paiement.

NGINX comme cache Web : un exemple conceptuel

Même sans utiliser Varnish, NGINX peut toujours jouer un rôle de cache via proxy_cache o fastcgi_cacheLa logique reste similaire : définir une clé de cache, décider quand contourner le système, décider quand ne pas enregistrer la réponse et ajouter des en-têtes de diagnostic.

Exemple simplifié avec proxy inverse :

proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=WORDPRESS:100m inactive=60m max_size=5g;

map $http_cookie $skip_cache_cookie {
default 0;
~wordpress_logged_in_ 1;
~woocommerce_items_in_cart=1 1;
~wp_woocommerce_session_ 1;
}

map $request_uri $skip_cache_uri {
default 0;
~^/wp-admin 1;
~^/wp-login.php 1;
~^/(cart|checkout|my-account) 1;
~add-to-cart= 1;
~wc-ajax= 1;
}

server {
location / {
proxy_pass http://backend_wordpress;

```
    proxy_cache WORDPRESS;
    proxy_cache_key "$scheme$request_method$host$request_uri";

    proxy_cache_bypass $skip_cache_cookie $skip_cache_uri $http_authorization;
    proxy_no_cache     $skip_cache_cookie $skip_cache_uri $http_authorization;

    proxy_cache_valid 200 301 302 60m;
    proxy_cache_valid 404 5m;

    add_header X-Cache-Status $upstream_cache_status always;
}
```

}

La distinction entre proxy_cache_bypass e proxy_no_cache C'est important. La première directive indique à NGINX de ne pas récupérer la réponse depuis le cache sous certaines conditions. La seconde indique à NGINX de ne pas enregistrer la réponse obtenue du serveur. Dans de nombreuses configurations, ces directives doivent être utilisées conjointement, car une requête privée ne doit ni lire une copie partagée ni alimenter le cache avec une réponse privée.

Ordinateur de bureau et mobile : le problème des mises en page différentes

De nombreux sites WordPress modernes utilisent le CSS adaptatif et servent donc le même code HTML aux ordinateurs et aux appareils mobiles. C'est le cas idéal pour la mise en cache : une seule URL, une seule réponse HTML, un seul objet mis en cache. La mise en page change dans le navigateur grâce aux requêtes média CSS, et non sur le serveur.

Le problème survient lorsque le serveur génère un code HTML différent selon l'agent utilisateur. Par exemple :

<?php if ( wp_is_mobile() ) : ?>

```
<div class="mobile-menu">Menu mobile</div>
```

<?php else : ?>

```
<div class="desktop-menu">Menu desktop</div>
```

<?php endif; ?>

Si cette logique se trouve dans une page pouvant être mise en cache, le premier appareil à générer le cache peut déterminer le code HTML servi aux autres. Si le cache contient la version mobile, les utilisateurs d'ordinateurs de bureau recevront également le balisage mobile. S'il contient la version pour ordinateur de bureau, les utilisateurs mobiles recevront le balisage pour ordinateur de bureau.

Il existe trois stratégies possibles.

La première approche, généralement préférable, consiste à laisser le code HTML inchangé . Générez un balisage compatible avec les deux appareils et laissez le CSS adapter l'interface.

La seconde consiste à créer une variante de cache explicite. Dans Varnish, vous pouvez par exemple normaliser l'en-tête User-Agent dans un en-tête synthétique. X-UA-Device, avec des valeurs limitées telles que desktop e mobileIncluez ensuite cet en-tête dans la logique de variation. Il est important de ne pas utiliser l'intégralité de l'en-tête User-Agent directement comme clé de cache, car cela générerait des milliers de variations quasiment inutiles.

sub vcl_recv {
if (req.http.User-Agent ~ "(?i)mobile|android|iphone") {
set req.http.X-UA-Device = "mobile";
} else {
set req.http.X-UA-Device = "desktop";
}
}

sub vcl_hash {
hash_data(req.http.X-UA-Device);
}

La troisième stratégie consiste à utiliser des URL distinctes, telles que /m/ ou des paramètres spécifiques, mais c'est rarement conseillé pour les sites WordPress standard de nos jours, car cela complique le référencement, les balises canoniques, les redirections, l'analyse et la maintenance.

En général, le développeur doit éviter wp_is_mobile() Il s'agit de déterminer le contenu essentiel des pages mises en cache. Cela peut se justifier pour des micro-optimisations, mais si cela génère un balisage différent, une stratégie claire de gestion des variations de cache doit s'y ajouter.

Le problème GeoIP

La géolocalisation IP est un autre point délicat. De nombreux sites souhaitent afficher un contenu différent selon le pays : devise, bannières, disponibilité des produits, mentions légales, TVA, frais de livraison, langue ou promotions locales. Le problème est que l’adresse IP est variable et parfois instable. De plus, si le cache n’est pas correctement initialisé, on risque d’afficher à un utilisateur italien une page générée pour un utilisateur allemand, ou de créer une variante de cache pour chaque adresse IP, ce qui nuit à son efficacité.

La règle est la suivante : ne jamais modifier directement le cache en fonction de l’adresse IP de l’utilisateur , sauf dans des cas très spécifiques et contrôlés. Il convient plutôt de normaliser les données. Par exemple, vous pouvez convertir l’adresse IP en un code pays et utiliser uniquement ce code pour différencier le cache.

IT → versione Italia
DE → versione Germania
FR → versione Francia
OTHER → versione generica

Là encore, il convient de se demander s'il est réellement nécessaire de générer du code HTML différent côté serveur. Dans bien des cas, il est préférable de proposer une page publique commune et d'utiliser JavaScript pour afficher un message local, suggérer un taux de change ou une version linguistique. Si le contenu localisé n'est pas essentiel pour le référencement naturel ou la conformité, son chargement côté navigateur est souvent plus sûr pour la mise en cache.

WooCommerce rend le thème encore plus sensible. Si le prix varie selon le pays, la devise ou le régime fiscal, la page produit n'est plus universellement partageable. Les alternatives sont les suivantes :

  • cache séparé pour le pays ou la devise normalisée ;
  • prix chargé via un point de terminaison dynamique ;
  • page publique avec prix standard et calcul personnalisé uniquement dans le panier ;
  • contournement pour les marchés ou les listes de prix véritablement personnalisés ;
  • Architecture multisite ou multi-magasins lorsque les différences sont structurelles.

Le choix dépend du modèle économique. Un blog avec une bannière localisée peut utiliser JavaScript. Un site e-commerce avec TVA, frais de port et tarification différenciée doit concevoir le cache en même temps que la logique commerciale et fiscale.

Hachage du cache dans Varnish : comment créer plusieurs versions contrôlées d’une même page

Pour bien comprendre comment Varnish peut servir plusieurs versions d'une même page sans les confondre, il est nécessaire d'introduire le concept de hachage du cache . Lorsque Varnish met une réponse en cache, il ne se contente pas de la stocker « par URL » de manière générique. En interne, il construit une clé de cache , qui sert d'identifiant pour retrouver l'objet mis en cache lors des requêtes suivantes.

Concrètement, la clé de cache répond à une question précise : cette requête peut-elle utiliser le même objet mis en cache qu’une requête précédente ? Si oui, Varnish peut traiter la requête. Si un élément pertinent change, Varnish doit rechercher un autre objet ou interroger le serveur pour générer une nouvelle variante.

Par défaut, Varnish construit le hachage à l'aide de blocs de construction comme req.url e req.http.hostCela signifie que, normalement, ces deux requêtes aboutissent sur des objets de cache différents :

https://www.example.com/prodotto/maglia/
https://www.example.com/categoria/t-shirt/

De même, si le même Varnish dessert plusieurs domaines, l'hôte entre également dans la logique de séparation :

[www.example.com/prodotto/maglia/](http://www.example.com/prodotto/maglia/)
shop.example.com/prodotto/maglia/

Même si le chemin d'accès est identique, un domaine différent doit générer un cache différent. Il serait dangereux de diffuser sur un autre hôte du contenu généré pour un hôte donné.

Le point intéressant est que Varnish permet d'étendre cette logique via la sous-routine. vcl_hashIci, vous pouvez définir les éléments qui doivent contribuer à la clé de cache. Autrement dit, vous pouvez indiquer à Varnish : « Cette page ne change pas seulement en fonction de l’URL et de l’hôte, mais aussi en fonction de l’appareil, de la langue, du pays, de la devise ou d’autres paramètres normalisés de l’application. »

La clé de cache n'a pas besoin de tout contenir : elle ne doit contenir que ce qui modifie réellement le code HTML.

L'une des erreurs les plus fréquentes consiste à croire que, pour des raisons de sécurité, il est judicieux d'inclure de nombreuses données dans la clé de cache : cookies, agent utilisateur complet, adresse IP, divers en-têtes, paramètres de suivi et préférences de l'utilisateur. En réalité, c'est tout le contraire de la bonne approche.

Une clé de cache efficace ne doit inclure que les éléments qui modifient réellement la réponse HTML . Tout autre élément génère une fragmentation inutile.

Si une page produit WooCommerce est identique pour tous les utilisateurs anonymes, il est inutile de créer une version différente pour chaque cookie d'analyse. Si le contenu ne change pas en fonction de _ga, _fbp, gclid o utm_sourceCes éléments ne doivent pas être inclus dans le hachage. Sinon, Varnish risquerait de stocker de nombreuses copies identiques de la même page, ce qui réduirait considérablement le taux de réussite.

Le principe à suivre est le suivant :

Ne modifiez le cache que lorsque le contenu servi change, et non lorsque seul le contexte de la requête change.

Comment fonctionne vcl_hash

Le sous-programme vcl_hash permet d'ajouter des données à la clé de recherche via hash_data()Un schéma simplifié pourrait être le suivant :

sub vcl_hash {
hash_data(req.url);

```
if (req.http.host) {
    hash_data(req.http.host);
} else {
    hash_data(server.ip);
}

return (lookup);
```

}

Voici la logique de base : URL et hôtes. Cependant, dans un projet WordPress ou WooCommerce réel, il peut arriver qu’une même URL doive comporter plusieurs variantes mises en cache. L’important est que ces variantes soient peu nombreuses, prévisibles et maîtrisées.

Par exemple, si votre site génère un code HTML différent pour les ordinateurs et les appareils mobiles, vous pouvez ajouter une valeur normalisée comme X-UA-Device:

sub vcl_recv {
if (req.http.User-Agent ~ "(?i)mobile|android|iphone") {
set req.http.X-UA-Device = "mobile";
} else {
set req.http.X-UA-Device = "desktop";
}
}

sub vcl_hash {
hash_data(req.url);

```
if (req.http.host) {
    hash_data(req.http.host);
} else {
    hash_data(server.ip);
}

hash_data(req.http.X-UA-Device);

return (lookup);
```

}

Dans ce cas, Varnish pourra conserver deux versions de la même URL :

/prodotto/maglia/ + desktop
/prodotto/maglia/ + mobile

Cela évite le problème classique où le premier visiteur mobile génère une page mise en cache qui est ensuite également servie aux utilisateurs d'ordinateurs de bureau, ou vice versa.

Normaliser avant le hachage

L'élément crucial n'est pas seulement l'ajout de données au hachage, mais leur normalisation préalable . Il ne faut jamais insérer directement dans le hachage des valeurs trop variables, telles que l'intégralité de l'en-tête User-Agent, l'adresse IP complète ou l'intégralité de l'en-tête Cookie.

Un agent utilisateur peut contenir des centaines, voire des milliers de combinaisons différentes. S'il est utilisé directement dans la clé de cache, une même page peut avoir un très grand nombre de copies en cache :

/prodotto/maglia/ + Chrome iPhone versione X
/prodotto/maglia/ + Chrome iPhone versione Y
/prodotto/maglia/ + Safari iPhone versione Z
/prodotto/maglia/ + Chrome Android modello A
/prodotto/maglia/ + Chrome Android modello B
/prodotto/maglia/ + Firefox Desktop versione N

La plupart de ces versions seraient inutiles. Si le code HTML ne change qu'entre les versions mobile et ordinateur, la clé de cache n'a besoin de faire la distinction qu'entre les deux. mobile e desktopPas parmi tous les navigateurs du monde.

Il en va de même pour GeoIP. Vous ne devez pas utiliser l'adresse IP du visiteur dans le hachage. Vous devez la convertir en une classification plus stable, par exemple :

IT
DE
FR
US
OTHER

Ce n'est qu'après cette normalisation que la valeur peut être utilisée pour créer des variantes mises en cache.

Exemple : Cache différent pour chaque pays GeoIP

Imaginons une boutique WooCommerce affichant des messages différents selon le pays du visiteur. Pour l'Italie, elle affiche « Livraison gratuite pour les commandes supérieures à 99 € », pour l'Allemagne, un message différent, et pour tous les autres pays, un message générique.

Dans ce cas, il n'est pas judicieux de créer un cache pour chaque adresse IP. Il est plus pertinent de créer trois variantes :

country=IT
country=DE
country=OTHER

Le VCL pourrait être conceptuellement similaire à ceci :

sub vcl_recv {
# Esempio: l'header X-Country viene impostato da un load balancer,
# da una CDN o da una logica GeoIP precedente a Varnish.

```
if (req.http.X-Country == "IT") {
    set req.http.X-Cache-Country = "IT";
} elseif (req.http.X-Country == "DE") {
    set req.http.X-Cache-Country = "DE";
} else {
    set req.http.X-Cache-Country = "OTHER";
}
```

}

sub vcl_hash {
hash_data(req.url);

```
if (req.http.host) {
    hash_data(req.http.host);
} else {
    hash_data(server.ip);
}

hash_data(req.http.X-Cache-Country);

return (lookup);
```

}

Avec cette configuration, une même URL peut avoir plusieurs objets mis en cache, mais toujours de manière contrôlée :

/prodotto/maglia/ + IT
/prodotto/maglia/ + DE
/prodotto/maglia/ + OTHER

Cette approche est très différente du contournement complet du cache. Contourner le cache signifie : « Je n’utilise pas le cache dans ce cas précis. » La variation de hachage, en revanche, signifie : « J’utilise le cache, mais je fais la distinction entre les versions réellement différentes. »

Exemple : Cache différent par langue

Dans un système WordPress multilingue, il est essentiel de comprendre où se trouvent les informations de langue. Si la langue figure dans l'URL, par exemple :

/it/prodotto/maglia/
/en/product/t-shirt/
/de/produkt/t-shirt/

alors souvent, il n'est pas nécessaire d'ajouter quoi que ce soit d'autre au hachage, car req.url C'est déjà différent. Varnish interprète des URL différentes et stocke des objets différents.

Le problème survient lorsque le langage dépend de cookies ou d'en-têtes, par exemple :

/prodotto/maglia/ + cookie lingua=it
/prodotto/maglia/ + cookie lingua=en

Dans ce cas, vous devez décider si la langue doit être incluse dans le cache de clés. Toutefois, il n'est pas nécessaire de hacher l'intégralité du cookie. Il suffit d'extraire la valeur pertinente et de la transformer en un en-tête normalisé :

sub vcl_recv {
if (req.http.Cookie ~ "site_lang=it") {
set req.http.X-Cache-Lang = "it";
} elseif (req.http.Cookie ~ "site_lang=en") {
set req.http.X-Cache-Lang = "en";
} elseif (req.http.Cookie ~ "site_lang=de") {
set req.http.X-Cache-Lang = "de";
} else {
set req.http.X-Cache-Lang = "default";
}
}

sub vcl_hash {
hash_data(req.url);

```
if (req.http.host) {
    hash_data(req.http.host);
} else {
    hash_data(server.ip);
}

hash_data(req.http.X-Cache-Lang);

return (lookup);
```

}

Dans un projet bien conçu, pour des raisons de référencement et de clarté architecturale, il est souvent préférable d'inclure la langue dans l'URL. Cela réduit l'ambiguïté et simplifie la gestion des URL canoniques, des sitemaps, des attributs hreflang et du cache.

Exemple WooCommerce : Devises différentes

WooCommerce peut se complexifier lorsque les prix et les devises varient selon le pays, la langue ou les préférences de l'utilisateur. Si une même fiche produit affiche des prix en euros, en dollars ou en livres sterling, il est impossible de proposer le même cache HTML à tous les utilisateurs.

Une solution consiste à créer une variante de cache par devise :

sub vcl_recv {
if (req.http.Cookie ~ "currency=EUR") {
set req.http.X-Cache-Currency = "EUR";
} elseif (req.http.Cookie ~ "currency=USD") {
set req.http.X-Cache-Currency = "USD";
} elseif (req.http.Cookie ~ "currency=GBP") {
set req.http.X-Cache-Currency = "GBP";
} else {
set req.http.X-Cache-Currency = "EUR";
}
}

sub vcl_hash {
hash_data(req.url);

```
if (req.http.host) {
    hash_data(req.http.host);
} else {
    hash_data(server.ip);
}

hash_data(req.http.X-Cache-Currency);

return (lookup);
```

}

La page produit peut donc exister en plusieurs versions :

/prodotto/maglia/ + EUR
/prodotto/maglia/ + USD
/prodotto/maglia/ + GBP

Attention : chaque nouvelle dimension ajoutée au hachage multiplie le nombre de variations. Si une page varie selon l’appareil, le pays et la devise, le nombre total d’éléments peut croître rapidement.

Par exemple:

2 dispositivi x 5 paesi x 3 valute = 30 varianti per URL

Si le catalogue compte 10 000 produits, le nombre potentiel d'objets mis en cache devient très élevé. Ce n'est pas toujours un problème, mais il est essentiel de le prendre en compte dès la conception. Un cache d'entreprise ne doit pas se contenter de « tout mettre en cache » : il doit mettre en cache uniquement les éléments qui apportent un réel avantage.

Variantes de cache et cookies WooCommerce

Avec WooCommerce, il convient de faire la distinction entre les cookies qui indiquent un état privé et les cookies qui indiquent une variante publique.

Un biscuit comme woocommerce_items_in_cart=1 Indique que l'utilisateur a des produits dans son panier. Dans de nombreux cas, il est inutile de créer une version publique de la page produit pour cet état, car le panier est personnel. L'option la plus sûre consiste à ignorer le cache de la page complète pour certaines requêtes ou, mieux encore, à continuer d'afficher la page publique mise en cache et à mettre à jour le mini-panier via JavaScript.

Un cookie spécifiant une devise ou une langue est différent si cette devise ou langue génère un code HTML identique pour un groupe d'utilisateurs. Dans ce cas, le cookie ne représente pas un utilisateur spécifique, mais une variante partageable . Il peut donc être extrait, normalisé et utilisé dans le hachage.

La distinction est fondamentale :

  • cookies de session personnelle: n'a normalement pas besoin de générer de cache public partagé ;
  • cookie de préférence partageable: peut générer une variante, si le contenu est identique pour tous les utilisateurs ayant cette préférence ;
  • cookies de suivi: ne doit pas affecter le hachage et doit être ignoré par le cache ;
  • cookies d'authentification: conduit généralement à un contournement ou à une gestion très contrôlée des applications.

Quand utiliser les variantes de hachage et quand utiliser JavaScript

Tout ce qui change ne doit pas forcément devenir une variante de cache. Parfois, il est préférable d'utiliser JavaScript.

La mise en cache variable est recommandée lorsque différents contenus sont importants pour la première réponse HTML, le référencement naturel, le rendu initial ou la cohérence commerciale. Par exemple :

  • page dans une autre langue ;
  • prix dans une autre devise déjà indexé ou visible dans la marge ;
  • Une disposition côté serveur véritablement différente pour les appareils mobiles et les ordinateurs de bureau ;
  • Messages juridiques obligatoires par pays ;
  • Un catalogue différent pour chaque marché.

JavaScript est souvent préférable pour les éléments petits, personnels ou non essentiels lors du premier rendu :

  • nombre de produits dans le panier ;
  • nom de l'utilisateur connecté ;
  • liste de souhaits ;
  • Bannière promotionnelle fermée par l'utilisateur ;
  • préférence graphique ;
  • contenu « récemment consulté » ;
  • notifications privées.

Autrement dit : si la différence concerne une petite partie de l’interface, il est préférable de ne pas multiplier le cache. Servez une page publique et complétez les détails côté navigateur. En revanche, si la différence concerne l’intégralité du document HTML, une variante de hachage peut convenir.

Exemple complet : appareil, pays et langue

Dans un cas plus complexe, vous pourriez vouloir distinguer le cache selon trois dimensions : appareil, pays et langue. Le VCL devrait d’abord normaliser toutes les valeurs, puis les utiliser dans vcl_hash.

sub vcl_recv {
# Normalizzazione dispositivo
if (req.http.User-Agent ~ "(?i)mobile|android|iphone") {
set req.http.X-Cache-Device = "mobile";
} else {
set req.http.X-Cache-Device = "desktop";
}

```
# Normalizzazione paese
if (req.http.X-Country == "IT") {
    set req.http.X-Cache-Country = "IT";
} elseif (req.http.X-Country == "DE") {
    set req.http.X-Cache-Country = "DE";
} else {
    set req.http.X-Cache-Country = "OTHER";
}

# Normalizzazione lingua
if (req.url ~ "^/it/") {
    set req.http.X-Cache-Lang = "it";
} elseif (req.url ~ "^/en/") {
    set req.http.X-Cache-Lang = "en";
} elseif (req.url ~ "^/de/") {
    set req.http.X-Cache-Lang = "de";
} else {
    set req.http.X-Cache-Lang = "default";
}
```

}

sub vcl_hash {
hash_data(req.url);

```
if (req.http.host) {
    hash_data(req.http.host);
} else {
    hash_data(server.ip);
}

hash_data(req.http.X-Cache-Device);
hash_data(req.http.X-Cache-Country);
hash_data(req.http.X-Cache-Lang);

return (lookup);
```

}

Cela génère une clé de cache plus riche, tout en restant maîtrisée. L'URL n'est plus une entité unique, mais un ensemble d'objets mis en cache. Chaque objet représente une combinaison spécifique de variantes.

Il est toutefois important de tenir compte du coût combinatoire. Si l'on ajoute trop de dimensions, le cache se fragmente. Si l'on en ajoute trop peu, on risque de servir un contenu erroné. La solution idéale se situe entre les deux : peu de variations, très claires, toutes justifiées par une réelle différence dans le code HTML.

Attention aux purges : invalidez toutes les variantes

Lors de l'utilisation de variantes de hachage, la purge doit également être prise en compte. Si une fiche produit comporte plusieurs versions en cache pour chaque langue, appareil et pays, il ne suffit pas d'ignorer la page produit. Il est impératif de s'assurer que l'invalidation supprime toutes les variantes valides.

Si vous effectuez une purge ponctuelle basée uniquement sur une URL, assurez-vous que votre logique VCL supprime tous les objets associés à cette URL, et non une seule variante. Dans certains cas, il est préférable d'utiliser des interdictions basées sur les URL, les hôtes, les étiquettes ou les clés de substitution pour invalider des groupes d'objets liés.

Ceci est particulièrement important pour WordPress et WooCommerce. Lorsqu'un prix de produit change, toutes les versions en cache de sa page produit doivent être supprimées : version ordinateur, mobile, italienne, anglaise, en euros, en dollars, etc. Si une seule variante est purgée, certains utilisateurs risquent de continuer à voir des données obsolètes.

Hachage Varnish et responsabilité du développeur

Le hachage du cache n'est pas seulement un problème système. Il influe aussi directement sur le développement d'applications. Le développeur doit connaître les conditions qui modifient le rendu HTML et les communiquer de manière prévisible à la couche de cache.

Dans le cas de WordPress et WooCommerce, cela signifie éviter une logique cachée et difficile à contrôler. Si une extension modifie son prix en fonction d'un cookie, ce cookie doit être connu. Si un thème modifie sa mise en page en fonction de… wp_is_mobile()Le cache doit comporter une version mobile et une version ordinateur. Si un système B2B affiche des listes de prix différentes selon le rôle de l'utilisateur, il convient de décider s'il faut les ignorer, les faire varier par groupe ou les charger dynamiquement.

Une bonne architecture doit clairement documenter :

  • quelles pages sont publiques et partageables ;
  • quelles pages sont privées et toujours accessibles en mode passif ;
  • quels cookies peuvent être ignorés ;
  • quels cookies indiquent une session ou une connexion ;
  • quels en-têtes entrent dans le cache de clés ;
  • quelles variantes existent pour chaque URL ;
  • comment toutes les variantes sont éliminées.

Ce document doit être partagé entre les développeurs, les ingénieurs système et les responsables du site e-commerce. Sans cette vision partagée, Varnish risque d'être correctement configuré techniquement, mais compromis par un comportement imprévisible de l'application.

En résumé : différents caches, oui, mais seulement en cas de besoin.

Le hachage Varnish permet de créer plusieurs versions mises en cache d'une même URL, ce qui facilite la gestion de cas complexes comme la compatibilité mobile/ordinateur, la langue, la devise, le pays ou d'autres états partagés de l'application. C'est un outil très puissant car il évite le faux dilemme entre « un cache unique pour tous » et « contournement total ».

Il est préférable de ne pas supprimer le cache dès qu'une différence apparaît, mais de déterminer si cette différence peut être transformée en une variante contrôlée. Lorsque cela est possible, Varnish peut gérer différents objets aussi efficacement qu'un cache classique, à condition que la clé de cache soit bien conçue.

La règle finale est simple : il ne faut pas hacher tout ce qui provient du client, mais seulement ce qui modifie réellement le contenu de la réponse . Les URL, les noms d’hôte, les appareils normalisés, les pays normalisés, les langues ou les devises sont d’excellents candidats. En revanche, les cookies complets, les adresses IP complètes, les agents utilisateurs bruts et les paramètres de suivi sont presque toujours trop bruités.

Pour WordPress et WooCommerce, cette approche garantit des performances élevées même dans des scénarios complexes : catalogues multilingues, boutiques multidevises, contenu localisé, mises en page différenciées et campagnes marketing. Elle exige cependant une méthode rigoureuse. Le cache ne doit pas suivre l’état de l’application de manière aléatoire : il doit recevoir des signaux clairs, standardisés et stables de la part de l’équipe de développement.

Utilisateurs connectés : quand contourner et quand séparer

L'utilisation d'utilisateurs connectés est l'une des principales causes du contournement du cache. WordPress utilise des cookies d'authentification et un cookie spécifique. wordpress_logged_in_* ce qui indique le statut de connexion. Si une requête contient ce cookie, le cache doit être très vigilant, car le serveur pourrait générer du contenu personnalisé.

Pour un site éditorial, le choix le plus simple est souvent le suivant : les utilisateurs anonymes sont servis par le cache, les utilisateurs connectés par mot de passe. Cette solution convient lorsque le nombre d’utilisateurs connectés est faible par rapport au trafic anonyme.

Pour les sites d'adhésion, les plateformes de formation en ligne, les sites communautaires ou les sites B2B, contourner tous les utilisateurs connectés peut toutefois annuler une grande partie des avantages. Dans ces cas, une conception plus élaborée est nécessaire.

  • Les pages publiques sont mises en cache même pour les utilisateurs connectés, si elles sont identiques ;
  • extraits personnels chargés via JavaScript ;
  • points de terminaison privés et non mis en cache pour les notifications et les données de compte ;
  • mettre en cache par rôle ou groupe, si le contenu est identique pour tous les utilisateurs du même groupe ;
  • entête Cache-Control: private sur les pages véritablement personnelles.

L'objectif n'est pas de dire « utilisateur connecté = cache impossible ». Il s'agit plutôt de comprendre quelles parties de la page dépendent réellement de l'identité de l'utilisateur. Si seul le texte « Salut Marco » change, il est inutile de rendre une page entière de 200 Ko non cachable. On met la page en cache et on actualise la barre d'informations de l'utilisateur avec JavaScript.

JavaScript comme allié du cache

JavaScript est souvent perçu comme un facteur de ralentissement, mais avec la mise en cache HTTP, il peut devenir un atout précieux. La raison est simple : elle permet de servir une page HTML publique et mise en cache, laissant au navigateur le soin de gérer les petites parties dynamiques.

Exemples d'éléments qui se prêtent bien à une gestion avec JavaScript :

  • statut de connexion dans le menu ;
  • nombre de produits dans le panier ;
  • liste de souhaits ;
  • messages de consentement aux cookies ;
  • bannières déjà fermées par l'utilisateur ;
  • Produits récemment consultés ;
  • notifications lumineuses ;
  • préférences d'interface ;
  • contenu GeoIP non critique ;
  • suivi et campagnes.

Prenons l'exemple du mini-panier WooCommerce. Si le nombre de produits dans le panier est affiché côté serveur dans l'en-tête, la page entière risque de devoir être modifiée à chaque session. Il est préférable d'afficher un espace réservé pouvant être mis en cache.

 <a href="/cart/" class="cart-link">
Carrello <span id="cart-count" data-default="0">0</span> </a>

Mettez ensuite à jour le numéro via le point de terminaison :

fetch('/wp-json/ms/v1/cart-count', {
credentials: 'same-origin'
})
.then(response => response.ok ? response.json() : { count: 0 })
.then(data => {
const counter = document.getElementById('cart-count');
if (counter) {
counter.textContent = data.count || 0;
}
});

Cette architecture présente un avantage considérable : la page d’accueil reste identique pour tous les utilisateurs, tandis que les données privées transitent par une requête distincte. Cette dernière peut être exclue du cache, protégée, limitée, optimisée et surveillée sans compromettre la mise en cache globale du site.

AJAX, API REST et admin-ajax.php

Il existe plusieurs façons de fournir des données dynamiques dans WordPress : admin-ajax.php, API REST, points de terminaison personnalisés, modèles dédiés ou appels WooCommerce wc-ajaxDu point de vue de la mise en cache, il est important que ces points de terminaison soient clairement séparés des pages publiques.

admin-ajax.php Bien qu'elle soit largement utilisée, cette méthode peut devenir un goulot d'étranglement car elle charge WordPress et est souvent sollicitée fréquemment. L'API REST permet une optimisation plus poussée, notamment pour les points de terminaison personnalisés bien conçus. Dans les deux cas, il convient d'éviter les appels inutiles, les interrogations excessives et les réponses non mises en cache lorsqu'un cache privé ou public, même court, est envisageable.

Exemple de point de terminaison REST pour une barre d'utilisateur :

add_action('rest_api_init', function () {
register_rest_route('ms/v1', '/user-bar', [
'methods'  => 'GET',
'callback' => function () {
if (!is_user_logged_in()) {
return [
'logged_in' => false,
];
}

```
        $user = wp_get_current_user();

        return [
            'logged_in' => true,
            'name'      => $user->display_name,
            'account'   => wc_get_page_permalink('myaccount'),
        ];
    },
    'permission_callback' => '__return_true',
]);
```

});

Pour un tel point de terminaison, vous devez vous assurer que le cache ne le stocke pas comme une réponse publique identique pour tous. Vous pouvez utiliser des en-têtes spécifiques :

add_filter('rest_post_dispatch', function ($result, $server, $request) {
if ($request->get_route() === '/ms/v1/user-bar') {
nocache_headers();
}

```
return $result;
```

}, 10, 3);

La séparation est essentielle : le HTML public dans le cache de la page complète, les microdonnées personnelles en dehors du cache de la page complète.

Nonces, formulaires et pages en cache

WordPress utilise souvent des nonces pour protéger les actions et les formulaires. Le problème est qu'un nonce affiché sur une page en cache peut expirer ou être partagé de manière inappropriée. Cela peut entraîner des erreurs apparemment aléatoires : formulaires qui ne s'envoient pas, actions AJAX qui échouent, processus de paiement qui ne fonctionne pas correctement ou messages « session expirée ».

La solution dépend du type de formulaire. Un simple formulaire public, comme une newsletter gérée par un prestataire externe, peut ne pas nécessiter de jeton d'authentification WordPress côté serveur. Un formulaire qui modifie des données, soumet des commandes ou effectue des actions sensibles doit se trouver sur une page non mise en cache ou récupérer le jeton dynamiquement.

Pour WooCommerce, la page de paiement ne doit pas être mise en cache car elle contient des informations sur le statut, le jeton de sécurité, la session, les modes de livraison et les données client. Il n'est pas nécessaire d'optimiser cette page avec un cache complet. L'optimisation doit reposer sur des requêtes de qualité, un cache d'objets, un PHP performant, une base de données saine et un minimum de code redondant.

Chaînes de requête, UTM et fragmentation du cache

Un autre problème d'application sous-estimé concerne les chaînes de requête. Les URL comme :

/prodotto/example/?utm_source=facebook
/prodotto/example/?utm_source=google
/prodotto/example/?fbclid=...
/prodotto/example/?gclid=...

Ils peuvent créer de nombreuses copies en cache de la même page, même si le contenu HTML est identique. Ce phénomène est appelé fragmentation du cache : au lieu d’un seul objet réutilisé, des dizaines, voire des milliers, de variantes inutiles sont produites.

La solution consiste à normaliser ou à supprimer de la clé de cache les paramètres qui n'affectent pas le rendu. Avec Varnish, vous pouvez nettoyer l'URL ou utiliser des VMOD spécifiques ; avec NGINX, vous pouvez définir une clé de cache qui ignore certains paramètres ou réécrire les requêtes avant les recherches.

Mais attention : tous les paramètres ne sont pas inutiles. Dans WooCommerce, des paramètres comme le filtre de catégories, le tri, la pagination ou la recherche peuvent modifier le contenu. Ils doivent donc rester dans la clé de cache. Les paramètres de suivi comme utm_source, utm_medium, fbclid, gclid Normalement, ils ne devraient pas générer de variantes HTML.

En-têtes de diagnostic : rendre visible le comportement du cache

Un développeur ne peut pas travailler efficacement avec un cache invisible. Il est important de pouvoir déterminer si une réponse correspond à une requête réussie (HIT), manquée (MISS), ignorée (BYPASS), acceptée (PASS) ou expirée (EXPIRED). C'est pourquoi il est utile d'ajouter des en-têtes de diagnostic.

Avec Varnish, vous pouvez ajouter, par exemple :

sub vcl_deliver {
if (obj.hits > 0) {
set resp.http.X-Cache = "HIT";
} else {
set resp.http.X-Cache = "MISS";
}

```
set resp.http.X-Cache-Hits = obj.hits;
```

}

Avec NGINX :

add_header X-Cache-Status $upstream_cache_status always;

Ces en-têtes permettent au développeur de vérifier immédiatement si une modification du thème, de l'extension ou des en-têtes HTTP a corrompu le cache. Lors du débogage, il est également conseillé de vérifier :

  • Cache-Control;
  • Set-Cookie;
  • Cookie dans la demande ;
  • Vary;
  • code d'état ;
  • Méthode HTTP ;
  • chaîne de requête ;
  • en-tête d'authentification ;
  • Des redirections.

Une page publique qui revient toujours X-Cache: MISS o BYPASS Il convient d'analyser le problème. La cause est souvent un cookie, un en-tête no-cache, un plugin qui ouvre une session ou une variation non normalisée.

Varie : Puissant, mais à utiliser avec précaution

L'en-tête Vary Cela indique au cache que la réponse varie en fonction d'un ou plusieurs en-têtes de requête. C'est utile, mais cela peut s'avérer dangereux en cas de mauvaise utilisation.

Un exemple courant et judicieux est :

Vary: Accept-Encoding

Dans ce cas, le cache fait la distinction entre les réponses compressées et non compressées. Le cas le plus complexe est le suivant :

Vary: User-Agent

Cela peut générer un nombre considérable de variations en raison de la multitude d'agents utilisateurs. Il est préférable de commencer par normaliser l'agent utilisateur en quelques classes, telles que « ordinateur de bureau » et « mobile », puis de le faire varier à l'aide d'un en-tête synthétique contrôlé.

Encore plus risqué :

Vary: Cookie

Modifier l'en-tête Cookie de manière uniforme rend souvent le cache quasiment inutile, car chaque utilisateur peut avoir une combinaison de cookies différente. La meilleure stratégie consiste à éviter cette modification. Vary: Cookie générique et choisissez précisément les états qui doivent influencer le cache.

purge du cache et invalidation du contenu

Un cache utile doit également pouvoir être purgé. Dans WordPress, lorsqu'un article est mis à jour, que le prix d'un produit change ou qu'une catégorie est modifiée, il n'est pas toujours possible d'attendre l'expiration naturelle du TTL. Une stratégie de purge est donc nécessaire.

Sur un site WordPress simple, lorsque vous mettez à jour un article, vous devez au moins purger :

  • l'URL de la publication ;
  • la page d'accueil, si elle affiche les articles les plus récents ;
  • les catégories associées ;
  • les archives des étiquettes ;
  • flux ou pages connexes, s'ils sont en cache.

Dans WooCommerce, lorsqu'un produit est modifié, les éléments suivants peuvent être affectés :

  • page produit ;
  • catégorie de produit ;
  • page d'accueil si elle présente des produits phares ;
  • blocs « produits associés » ;
  • recherche interne ;
  • alimentation du produit ;
  • Page d'accueil avec code court WooCommerce.

La purge doit être ciblée, mais non naïve. Une purge insuffisante laisse du contenu obsolète. Une purge systématique après chaque modification engendre une avalanche de fichiers manquants et surcharge le serveur. Une bonne intégration WordPress/Varnish doit comprendre les relations entre les contenus et invalider les éléments concernés.

Le cache d'objets et le cache de page complète ne sont pas la même chose.

De nombreux développeurs confondent cache d'objets et cache de page complète. Ce sont des outils différents et complémentaires.

Le cache de page complète préserve la réponse HTML finale et peut contourner entièrement PHP. Varnish et le cache inversé NGINX fonctionnent à ce niveau.

Les caches d'objets , comme ceux utilisant Redis ou Memcached, stockent les résultats intermédiaires : requêtes, objets WordPress, données transitoires, options et données applicatives. PHP continue de s'exécuter, mais accède plus rapidement aux données pré-traitées.

Dans WooCommerce, un bon cache d'objets est essentiel pour le panier, la page de paiement, l'espace client et les utilisateurs connectés ; autrement dit, pour toutes les requêtes qui ne peuvent pas bénéficier du cache de page complète. Le cache de page complète accélère le trafic global ; le cache d'objets, quant à lui, optimise le trafic dynamique.

Une plateforme haute performance utilise les deux niveaux sans les confondre.

Liste de contrôle pour développeurs WordPress utilisant Varnish

Lors du développement ou de la modification d'un site WordPress/WooCommerce derrière Varnish ou un autre cache Web, il est conseillé de suivre une liste de contrôle pratique.

    • La page contient-elle des données différentes pour chaque utilisateur ?
    • Le thème utilise is_user_logged_in() imprimer du HTML personnalisé ?
    • Le plugin dépose-t-il des cookies sur toutes les pages ?
    • Une session PHP globale a-t-elle été démarrée ?
    • Le panier WooCommerce est-il imprimé côté serveur dans l'en-tête ?
    • Le prix varie-t-il selon le pays, la devise, le rôle ou le groupe ?
    • La version mobile génère-t-elle un code HTML différent ?
    • La langue est-elle indiquée dans l'URL ou dépend-elle des cookies/en-têtes ?
  • Les chaînes de requêtes de suivi fragmentent-elles le cache ?
  • Les pages panier, paiement et mon compte sont-elles exclues ?
  • Mes points de terminaison AJAX/REST personnels sont-ils exclus du cache public ?
  • Les en-têtes Cache-Control Sont-ils cohérents ?
  • La réponse contient Set-Cookie sans raison ?
  • Existe-t-il un système de purge après les mises à jour de contenu ?
  • Les en-têtes de diagnostic permettent-ils de visualiser HIT/MISS/BYPASS ?

Ces questions devraient faire partie intégrante du processus de développement normal, au même titre que la sécurité, le référencement, l'accessibilité et la compatibilité mobile.

Conclusion : Développer en tenant compte du cache

Le cache web n'est pas un frein au développement. Il améliore les performances, mais il exige une gestion rigoureuse. Le code de l'application doit clairement distinguer le contenu public du contenu privé, le HTML partageable des données personnelles, les cookies nécessaires des cookies superflus, les variantes réelles de la fragmentation accidentelle.

Varnish Cache, en particulier, offre un contrôle extrêmement puissant, mais il ne peut pas corriger une application qui génère des données privées partout. Si WordPress place des cookies inutiles sur chaque page, si WooCommerce est personnalisé en imprimant les données du panier et de l'utilisateur côté serveur dans chaque modèle, si la géolocalisation IP varie pour les adresses IP non normalisées, ou si la mise en page mobile est générée sans clé de cache cohérente, le cache perd de son efficacité.

La bonne méthode consiste à concevoir l'application avec une séparation claire :

  • HTML public et partageable servi par Varnish ou Web Cache ;
  • fragments personnels chargé via JavaScript, API REST ou points de terminaison dédiés ;
  • pages véritablement privées exclu du cache de la page complète ;
  • cookies contrôlés et non utilisé comme espace de stockage général ;
  • variantes normalisées pour les appareils mobiles, la langue, la devise ou le pays uniquement lorsque cela est nécessaire ;
  • purge cohérente lorsque le contenu change.

Pour un développeur WordPress et WooCommerce, bien utiliser Varnish signifie ne plus considérer une page comme constamment régénérée, pour tous et à chaque requête. Il s'agit plutôt de concevoir des réponses HTTP mises en cache, prévisibles et sécurisées. Résultat : un site plus rapide, un backend allégé, une meilleure résistance aux pics de trafic et une expérience utilisateur optimisée.

Dans une infrastructure gérée par des professionnels, la mise en cache n'est pas un simple plugin à activer. Elle est un élément central de l'architecture. Lorsque le développement applicatif, la configuration système et la logique métier fonctionnent de concert, Varnish déploie tout son potentiel : diffusion rapide des données publiques, protection des données privées et maintien des performances de WordPress et WooCommerce même en cas de forte charge.

Vous avez des doutes ? Vous ne savez pas par où commencer ? Contactez-nous !

Nous avons toutes les réponses à vos questions pour vous aider à faire le bon choix.

Discute avec nous

Discutez directement avec notre support avant-vente.

0256569681

Contactez-nous par téléphone pendant les heures de bureau 9h30 - 19h30

Contactez-nous en ligne

Ouvrez une demande directement dans l'espace contact.

AVIS DE NON-RESPONSABILITÉ, Mentions légales et droits d'auteur. Red Hat, Inc. détient les droits sur Red Hat®, RHEL®, RedHat Linux® et CentOS® ; AlmaLinux™ est une marque commerciale de la AlmaLinux OS Foundation ; Rocky Linux® est une marque déposée de la Rocky Linux Foundation ; SUSE® est une marque déposée de SUSE LLC ; Canonical Ltd. détient les droits sur Ubuntu® ; Software in the Public Interest, Inc. détient les droits sur Debian® ; Linus Torvalds détient les droits sur Linux® ; FreeBSD® est une marque déposée de la Fondation FreeBSD ; NetBSD® est une marque déposée de la Fondation NetBSD ; OpenBSD® est une marque déposée de Theo de Raadt ; Oracle Corporation détient les droits sur Oracle®, MySQL®, MyRocks®, VirtualBox® et ZFS® ; Percona® est une marque déposée de Percona LLC ; MariaDB® est une marque déposée de MariaDB Corporation Ab ; PostgreSQL® est une marque déposée de PostgreSQL Global Development Group ; SQLite® est une marque déposée de Hipp, Wyrick & Company, Inc. ; KeyDB® est une marque déposée d'EQ Alpha Technology Ltd. ; Typesense® est une marque déposée de Typesense Inc. ; REDIS® est une marque déposée de Redis Labs Ltd ; F5 Networks, Inc. détient les droits sur NGINX® et NGINX Plus® ; Varnish® est une marque déposée de Varnish Software AB ; HAProxy® est une marque déposée de HAProxy Technologies LLC ; Traefik® est une marque déposée de Traefik Labs ; Envoy® est une marque déposée de CNCF ; Adobe Inc. détient les droits sur Magento® ; PrestaShop® est une marque déposée de PrestaShop SA ; OpenCart® est une marque déposée d'OpenCart Limited ; Automattic Inc. détient les droits sur WordPress®, WooCommerce® et JetPack® ; Open Source Matters, Inc. détient les droits sur Joomla® ; Dries Buytaert détient les droits sur Drupal® ; Shopify® est une marque déposée de Shopify Inc. ; BigCommerce® est une marque déposée de BigCommerce Pty. Ltd.; TYPO3® est une marque déposée de la TYPO3 Association; Ghost® est une marque déposée de la Ghost Foundation; Amazon Web Services, Inc. détient les droits sur AWS® et Amazon SES® ; Google LLC détient les droits sur Google Cloud™, Chrome™ et Google Kubernetes Engine™ ; Alibaba Cloud® est une marque déposée d'Alibaba Group Holding Limited ; DigitalOcean® est une marque déposée de DigitalOcean, LLC ; Linode® est une marque déposée de Linode, LLC ; Vultr® est une marque déposée de The Constant Company, LLC ; Akamai® est une marque déposée d'Akamai Technologies, Inc. ; Fastly® est une marque déposée de Fastly, Inc. ; Let's Encrypt® est une marque déposée d'Internet Security Research Group ; Microsoft Corporation détient les droits sur Microsoft®, Azure®, Windows®, Office® et Internet Explorer® ; Mozilla Foundation détient les droits sur Firefox® ; Apache® est une marque déposée de The Apache Software Foundation ; Apache Tomcat® est une marque déposée de The Apache Software Foundation ; PHP® est une marque déposée de PHP Group ; Docker® est une marque déposée de Docker, Inc. Kubernetes® est une marque déposée de The Linux Foundation ; OpenShift® est une marque déposée de Red Hat, Inc. ; Podman® est une marque déposée de Red Hat, Inc. ; Proxmox® est une marque déposée de Proxmox Server Solutions GmbH ; VMware® est une marque déposée de Broadcom Inc. ; CloudFlare® est une marque déposée de Cloudflare, Inc. ; NETSCOUT® est une marque déposée de NETSCOUT Systems Inc. ; ElasticSearch®, LogStash® et Kibana® sont des marques déposées d'Elastic NV ; Grafana® est une marque déposée de Grafana Labs ; Prometheus® est une marque déposée de The Linux Foundation ; Zabbix® est une marque déposée de Zabbix LLC ; Datadog® est une marque déposée de Datadog, Inc. ; Ceph® est une marque déposée de Red Hat, Inc. ; MinIO® est une marque déposée de MinIO, Inc. ; Mailgun® est une marque déposée de Mailgun Technologies, Inc. ; SendGrid® est une marque déposée de Twilio Inc. Postmark® est une marque déposée d'ActiveCampaign, LLC ; cPanel®, LLC détient les droits sur cPanel® ; Plesk® est une marque déposée de Plesk International GmbH ; Hetzner® est une marque déposée de Hetzner Online GmbH ; OVHcloud® est une marque déposée d'OVH Groupe SAS ; Terraform® est une marque déposée de HashiCorp, Inc. ; Ansible® est une marque déposée de Red Hat, Inc. ; cURL® est une marque déposée de Daniel Stenberg ; Facebook®, Inc. détient les droits sur Facebook®, Messenger® et Instagram®. Ce site n'est pas affilié, sponsorisé ou autrement associé à l'une des entités mentionnées ci-dessus et ne représente aucune de ces entités de quelque manière que ce soit. Tous les droits sur les marques et noms de produits mentionnés sont la propriété de leurs titulaires respectifs des droits d'auteur. Toutes les autres marques mentionnées sont la propriété de leurs titulaires respectifs. MANAGED SERVER® est une marque déposée européenne de MANAGED SERVER SRL, dont le siège social est situé Via Flavio Gioia, 6, 62012 Civitanova Marche (MC), Italie et le siège opérationnel Via Enzo Ferrari, 9, 62012 Civitanova Marche (MC), Italie.

JUSTE UN MOMENT !

Vous êtes-vous déjà demandé si votre hébergement était nul ?

Découvrez dès maintenant si votre hébergeur vous pénalise avec un site web lent digne des années 1990 ! Résultats immédiats.

Fermer le CTA
Retour en haut de page