« Use efficient cache lifetimes » dans Lighthouse : comment le corriger

Lighthouse 13 liste chaque fichier que les navigateurs de vos visiteurs peuvent réutiliser pendant moins de 30 jours. Ce que cela coûte pour la page suivante et la visite de retour, et le fix par serveur et plateforme.

Arjen Karel Core Web Vitals Consultant
Arjen Karel - linkedin
Last update: 2026-10-17

« Use efficient cache lifetimes » pénalise-t-il votre score Lighthouse ?

Lighthouse signale chaque fichier statique dont la durée de cache est inférieure à 30 jours dans l'audit « Use efficient cache lifetimes » (« Une longue durée de mise en cache peut accélérer les visites répétées sur votre page »), appelé « Serve static assets with an efficient cache policy » avant Lighthouse 13 et « Leverage browser caching » dans les anciennes versions de PageSpeed Insights. Il ne compte pas dans votre score et ne peut pas le faire bouger : Lighthouse charge toujours avec un cache vide. Définissez des durées plus longues sur votre serveur, CDN ou plugin de cache.

Que signifie « Use efficient cache lifetimes » dans Lighthouse ?

La description de Lighthouse indique : « Une longue durée de mise en cache peut accélérer les visites répétées sur votre page. En savoir plus sur la mise en cache. »

Lighthouse liste chaque script, feuille de style, police, image, vidéo et fichier audio dont la durée de cache est inférieure à 30 jours, ou sans aucune durée définie. Cette durée correspond au max-age dans l'en-tête Cache-Control du fichier, ou au délai restant jusqu'à sa date Expires. Les fichiers provenant d'autres domaines sont listés au même titre que les vôtres.

Lighthouse ignore les fichiers dont le Cache-Control indique no-cache, no-store, private ou must-revalidate, quel que soit leur max-age : il considère qu'il s'agit d'un choix de ne pas mettre en cache. Il ignore aussi les fichiers avec max-age=0, et ne liste jamais la page HTML elle-même.

Lighthouse's Use efficient cache lifetimes insight, red, estimated savings of 444 KiB: thirteen of the shop's own files with a cache TTL of None and Meta's fbevents.js with 20 minutes; Google Tag Manager and gtag.js are not listed.

Une page qui charge Google Tag Manager, GA4 et le Meta Pixel. Google envoie ses tags en private, donc sur les trois, seul le Meta Pixel est listé. Lighthouse 13.5.0, throttling simulé comme dans PageSpeed Insights.

Comment fonctionne le cache du navigateur ?

Le navigateur stocke chaque fichier avec sa durée de validité. Sur la page suivante ou lors de la visite suivante, il consulte d'abord sa copie locale :

  • Pendant sa durée de validité : le navigateur utilise sa copie sans envoyer la moindre requête. C'est le seul cas où l'on n'attend pas le serveur.
  • Durée expirée : le navigateur demande au serveur si le fichier a changé, avec l'ETag ou la date Last-Modified reçus avec le fichier. Si rien n'a changé, le serveur répond 304 Not Modified, sans renvoyer le fichier. Cela évite le téléchargement, mais chaque fichier coûte tout de même un aller-retour vers le serveur, et la page ne peut pas s'afficher tant que le serveur n'a pas répondu pour chaque feuille de style.
  • Durée expirée sans ETag ni Last-Modified : le navigateur télécharge à nouveau le fichier.
En-tête sur le fichierAffichage suivant dans Chrome
max-age=31536000Depuis le cache pendant un an
max-age=14400Depuis le cache pendant 4 heures, puis un 304
no-cacheUn 304 à chaque fois
no-storeTéléchargé à chaque fois

Un rechargement normal dans Chrome ne revérifie pas les fichiers encore valides. Firefox et Safari le font, sauf si le fichier contient immutable dans son Cache-Control.

Depuis Chrome 86, chaque site a son propre cache. Une police ou un fichier jQuery déjà téléchargé par votre visiteur sur un autre site est retéléchargé sur le vôtre, même depuis la même URL. La durée de cache d'un tiers ne sert donc que sur votre propre site, pour la page suivante et la visite de retour. L'argument « tout le monde l'a déjà en cache » n'est plus une raison d'appeler des polices depuis Google (hébergez-les vous-même).

Le cache du navigateur et le cache de votre CDN sont deux choses différentes, tout comme le cache de page d'un plugin WordPress. Un CDN ou un cache de page garde une copie pour éviter au serveur de l'envoyer ou de la générer pour chaque visiteur, ce qui réduit le TTFB (durée de cache). Le cache du navigateur évite la requête entière, pour un visiteur. Cet audit ne concerne que le cache du navigateur : activer un cache de page ne le valide donc pas.

Une durée de cache plus longue améliore-t-elle le LCP et le FCP ?

FCP et LCP lors d'une première visite

Aucun changement. Sur une page produit WooCommerce, sur un téléphone en connexion Slow 4G, le premier affichage est survenu à 2,13 s et le LCP à 2,26 s avec chaque en-tête, d'aucun délai jusqu'à un an : lors d'une première visite, rien n'est encore en cache. Lighthouse et PageSpeed Insights chargent systématiquement les pages ainsi. Régler cet audit ne fait jamais bouger votre score ni vos métriques Lighthouse, même quand Lighthouse l'affiche en rouge avec des gains estimés de FCP et de LCP en face.

Lighthouse at phone width: score 96, LCP 2.4 s, and Use efficient cache lifetimes in red with 345 KiB of estimated savings, for files with no cache lifetime.

Aucune durée

Lighthouse at phone width: the same score 96 and LCP 2.4 s, the insight in red with 235 KiB, for files cached four hours.

Les 4 heures de Cloudflare

Lighthouse at phone width: the same score 96 and LCP 2.4 s, the insight passed, for files cached a year.

Un an

Lighthouse at phone width: the same score 96 and LCP 2.4 s, the insight passed, for files sent with no-store that are never cached.

no-store

La même page produit avec quatre en-têtes de cache sur ses fichiers. Lighthouse 13.5.0, mobile, throttling simulé.

FCP et LCP sur la page suivante et lors d'une visite de retour

Le premier affichage (FCP) en secondes, face aux 2,13 s de la première visite :

En-tête de cachePage suivanteUne semaine plus tard
un an0,790,78
4 heures0,801,94
no-cache1,931,94
no-store2,112,12
  • Le gain provient des fichiers encore valides en cache. Une semaine plus tard, la page avec une durée d'un an affichait son premier contenu à 0,78 s, environ un tiers de la première visite. Il ne reste plus que l'attente du document HTML. Lors de la visite de retour, le LCP (la photo du produit) est apparu au même moment que le premier affichage avec tous les en-têtes, sauf no-store (2,24 s).
  • Avec des 304, la visite de retour a été presque aussi lente qu'une première visite. Sans durée définie, une semaine plus tard, les 13 fichiers de la boutique ont renvoyé un 304 : 1 Ko sur le réseau au lieu de 404 Ko, et toujours un premier affichage à 1,94 s, soit seulement 0,19 s de moins qu'en retéléchargeant tout.
  • Les durées courtes couvrent la visite et expirent avant le retour. Les 4 heures de Cloudflare ont servi la page suivante depuis le cache. Une semaine plus tard, il a fallu des 304. Seule la durée d'un an a couvert les deux.
  • no-cache et no-store ralentissent chaque page. Ils ont fait passer la page suivante de 0,79 s à 1,93 s et 2,11 s.
A phone screen still blank 0.8 seconds into a return visit a week later, while each file is checked with the server.

Aucune durée, une semaine plus tard

The same product page complete at 0.8 seconds on a return visit a week later, every file from the browser's cache.

Durée d'un an, une semaine plus tard

Les deux pages à 0,8 s sur le téléphone bridé.

Sur une vraie connexion Slow 4G, chaque affichage prend plus de temps ; l'ordre entre les en-têtes reste le même. En Fast 4G, la durée d'un an a affiché la page à 0,52 s lors de la visite de retour, et le retour avec des 304 a pris 0,85 s, soit autant que la première visite sur cette connexion.

Quand pouvez-vous ignorer « Use efficient cache lifetimes » ?

Quand Lighthouse liste vos propres fichiers et que vos visiteurs reviennent des jours ou des semaines plus tard, réglez-le : cela demande une seule règle sur le serveur et ne coûte rien pendant le chargement de la page. Laissez de côté quand :

  • chaque fichier listé est sur un autre domaine ou servi par votre plateforme (voir ci-dessous) ; sur Shopify c'est systématiquement le cas ;
  • vos fichiers CSS et JavaScript changent sous le même nom et vous ne pouvez pas ajouter de version : une durée courte est alors le bon choix, et Lighthouse continuera de lister ces fichiers ;
  • la quasi-totalité des visiteurs ne consulte qu'une seule page et ne revient jamais, comme pour une landing page de campagne publicitaire : personne n'utilise le cache.

Comment mesurer l'effet des durées de cache dans vos field data ?

Vos field data mélangent premières visites, pages suivantes et visites de retour. Dans CoreDash, groupez le LCP sur mobile par Repeat Visitor, puis faites de même pour le TTFB :

CoreDash, LCP on mobile grouped by Repeat Visitor: repeat visitors 0.65 seconds at p75, new visitors 1.74 seconds, both rated good. CoreDash, TTFB on mobile grouped by Repeat Visitor: repeat visitors 323 ms at p75, rated good; new visitors 0.87 seconds, rated improve.

CoreDash sur un site de démo, acme-pagespeed.com : mobile, p75.

Les visiteurs récurrents ont un LCP de 0,65 s, contre 1,74 s pour les nouveaux visiteurs. Cet écart ne vient pas uniquement du cache : les visiteurs récurrents obtiennent aussi le premier octet plus vite, 323 ms contre 0,87 s, souvent parce que leur navigateur a déjà une connexion ouverte avec votre serveur. Soustrayez donc le TTFB du LCP. Après le premier octet, les visiteurs récurrents attendent 0,33 s et les nouveaux visiteurs 0,87 s. Ces 0,54 s correspondent à peu près à ce que le cache fait gagner, environ la moitié de l'écart ; le premier octet plus rapide représente l'autre moitié.

Pour analyser la page suivante d'une session de façon isolée, groupez par Navigation Origin : same origin signifie que le visiteur provient d'une autre page de votre site. CrUX regroupe toutes ces visites dans un seul p75 par page ou par site, et ne peut donc pas afficher cette distinction.

Comment vérifier les en-têtes de cache d'un fichier dans DevTools ?

Ouvrez le panneau Network et assurez-vous que Disable cache est désactivé (les réglages réseau de DevTools indiquent quand l'activer). Chargez votre page, puis cliquez vers une deuxième page. Les colonnes Status et Size montrent ce qui est arrivé à chaque fichier :

  • (disk cache) ou (memory cache) dans Size : servi depuis le cache, aucune requête.
  • 304 dans Status : le navigateur a interrogé le serveur et n'a reçu aucun fichier en retour.
  • 200 avec une taille : téléchargé à nouveau.
Chrome DevTools Network panel on a return visit: every stylesheet, script, font and the photo answered 304 with no bytes, each taking a round trip of about 600 ms.

Aucune durée : 304 pour chaque fichier

Chrome DevTools Network panel on a return visit: the HTML downloaded, every other file served from the disk cache in 1 to 3 ms.

Un an : depuis le cache disque

La visite de retour une semaine plus tard dans le panneau Network, en Slow 4G.

Cliquez sur un fichier et ouvrez son onglet Headers. Sous Response Headers, cache-control et expires affichent la durée envoyée par votre serveur, etag et last-modified ce que le navigateur peut revérifier. Depuis la ligne de commande :

curl -sI https://www.example.com/wp-content/themes/acme/style.css | grep -iE "cache-control|expires|etag|last-modified"

Le panneau Performance contient le même audit. Enregistrez un rechargement et ouvrez « Use efficient cache lifetimes » dans la barre latérale Insights : il liste les fichiers et les entoure dans la piste Network. Un fichier sans durée y apparaît avec 0 ms, et comme None dans Lighthouse. Il se base sur les en-têtes, si bien qu'un fichier issu du cache reste listé dès lors que sa durée est courte.

Chrome DevTools Performance panel with the Use efficient cache lifetimes insight open: the shop's files listed with a cache TTL of 0 ms and outlined in red in the Network track.

Comment corriger « Use efficient cache lifetimes » ?

Le domaine de chaque fichier listé par Lighthouse vous indique qui définit l'en-tête : sur votre propre domaine, c'est votre serveur, votre hébergeur ou votre CDN ; sur tout autre domaine, c'est le fournisseur de ce fichier.

nginx, Apache, IIS et Caddy

Sur votre propre serveur, une règle par type de fichier définit la durée. Ces règles appliquent un an avec immutable : utilisez-les pour les images, ainsi que pour les fichiers CSS, JavaScript et les polices dès lors que leurs URL portent une version (quelle durée pour quel fichier). Sous nginx :

location ~* \.(?:css|js|mjs|woff2|svg|png|jpe?g|gif|webp|avif|ico)$ {
    add_header Cache-Control "public, max-age=31536000, immutable";
}

Placez cette règle dans le bloc server qui sert ces fichiers depuis le disque. Si votre configuration comporte déjà une directive location pour ces extensions, ajoutez plutôt la ligne add_header à celle-ci, car nginx n'utilise que la première location regex qui correspond. Supprimez-en toute ligne expires, sinon les fichiers recevront deux en-têtes Cache-Control. Un add_header dans une location pousse nginx à ignorer tous les add_header du bloc server pour ces fichiers : recopiez donc aussi les lignes add_header du bloc server (votre en-tête HSTS, par exemple) dans cette location.

Sous Apache, placez ceci dans .htaccess :

<IfModule mod_headers.c>
  <FilesMatch "\.(css|js|mjs|woff2|svg|png|jpe?g|gif|webp|avif|ico)$">
    Header set Cache-Control "public, max-age=31536000, immutable"
  </FilesMatch>
</IfModule>

FilesMatch se base sur le nom du fichier ; les pages générées par PHP conservent donc leurs propres en-têtes. Si Lighthouse liste encore les fichiers par la suite, c'est que votre serveur n'applique pas la règle : mod_headers est désactivé, ou votre hébergeur sert ces fichiers depuis un autre serveur qui ignore le .htaccess. Demandez à votre hébergeur.

IIS n'envoie aucune durée par défaut. Définissez l'en-tête dans web.config, ciblé sur le dossier de vos fichiers statiques :

<configuration>
  <location path="assets">
    <system.webServer>
      <httpProtocol>
        <customHeaders>
          <add name="Cache-Control" value="public, max-age=31536000, immutable" />
        </customHeaders>
      </httpProtocol>
    </system.webServer>
  </location>
</configuration>

Sous Caddy :

@static path *.css *.js *.mjs *.woff2 *.svg *.png *.jpg *.jpeg *.gif *.webp *.avif *.ico
header @static Cache-Control "public, max-age=31536000, immutable"

WordPress

WordPress n'envoie de lui-même aucune durée pour le contenu de /wp-content/ ou /wp-includes/ : votre hébergeur, votre serveur ou un plugin s'en charge. Kinsta, WP Engine, WordPress VIP et WordPress.com envoient déjà un an : si vous êtes hébergé chez eux, les fichiers listés par Lighthouse se trouvent généralement sur d'autres domaines (voir ci-dessous). L'avertissement apparaît généralement sur les hébergements mutualisés Apache qui n'envoient aucune durée, sur un serveur nginx que vous gérez vous-même, et derrière la configuration par défaut de Cloudflare. Côté plugins de cache :

  • WP Rocket écrit des règles mod_expires dans le .htaccess sur les serveurs Apache et LiteSpeed : un an pour le CSS et le JavaScript, quatre mois pour les images et les polices. Sur nginx, il ne fait rien : ajoutez la règle nginx plus haut, ou demandez à votre hébergeur.
  • LiteSpeed Cache désactive Browser Cache par défaut. Activez-le sous LiteSpeed Cache, Cache, Browser ; il enverra alors un an.
  • W3 Total Cache active Browser Cache par défaut. Sur nginx, il écrit un fichier nginx.conf que vous devez inclure vous-même dans la configuration de votre serveur.

WordPress ajoute ?ver= à chaque feuille de style et script qu'il charge : la version de WordPress par défaut, ou celle transmise par le thème ou le plugin. Elle ne change que lors d'une mise à jour. Quand vous modifiez votre propre CSS sans changer de version, l'URL reste identique et les visiteurs qui reviennent conservent l'ancien CSS tant que sa durée court. Chargez vos propres fichiers avec leur date de modification comme version, afin que l'URL change à chaque édition :

add_action( 'wp_enqueue_scripts', function () {
  $file = '/css/custom.css';
  wp_enqueue_style( 'acme-custom', get_stylesheet_directory_uri() . $file, array(), filemtime( get_stylesheet_directory() . $file ) );
} );

Les téléversements n'ont pas de version. WordPress donne un nouveau nom à un fichier réimporté (photo-1.jpg), si bien qu'un an est sans risque, sauf si un plugin remplace les médias sous le même nom.

Cloudflare et autres CDN

Le Browser Cache TTL de Cloudflare est de 4 heures par défaut, sur tous les forfaits. Quand votre serveur n'envoie aucune durée ou une durée plus courte, Cloudflare envoie 4 heures, et Lighthouse liste le fichier avec « 4h ». Définissez les durées sur votre serveur et passez Browser Cache TTL (Caching, Configuration) sur Respect Existing Headers. Ou créez une Cache Rule pour vos types de fichiers statiques qui définit le TTL navigateur. Ne montez pas le réglage au niveau de la zone à un an : il s'appliquerait alors à chaque fichier servi par Cloudflare avec un en-tête plus court, y compris le CSS sans version. Retrouvez les autres réglages dans configurer Cloudflare pour les Core Web Vitals.

CloudFront et Fastly transmettent l'en-tête de votre serveur au navigateur ; leurs réglages de TTL ne changent que la durée de conservation de la copie sur le CDN. Sur Bunny, une règle Edge Rule avec Override Browser Cache Time définit la durée par extension de fichier.

Shopify

Shopify applique déjà un an aux fichiers de votre thème, aux fichiers téléversés et aux images de produits (public, max-age=31557600), et vous ne pouvez pas modifier les en-têtes de Shopify. Ce que Lighthouse liste sur Shopify vient de Shopify lui-même et de vos applications : les boutons de paiement dynamique (portable-wallets, 5 minutes, sur votre propre domaine sous /cdn/shopifycloud/), le loader shop-js (30 minutes) et le web pixels manager (60 secondes). Il n'y a rien à corriger. Ignorez l'avertissement.

Next.js et autres outils de build

Next.js applique à tout ce qui se trouve sous /_next/static/ un an avec immutable, et vous ne pouvez pas modifier cela. Les fichiers dans public/ reçoivent max-age=0 (sur Vercel avec must-revalidate) et /_next/image envoie must-revalidate ; l'audit ignore donc les deux. Sur un site Next.js, les fichiers listés par Lighthouse proviennent de tiers, ou d'un proxy ou CDN placé devant qui réécrit les en-têtes. Pour les fichiers dans public/ dont le nom change avec leur contenu, définissez un an dans next.config.js :

module.exports = {
  async headers() {
    return [{
      source: '/fonts/:path*',
      headers: [{ key: 'Cache-Control', value: 'public, max-age=31536000, immutable' }],
    }]
  },
}

Sur toute autre stack, laissez le bundler insérer un hash dans les noms de fichiers (app.3f9a1c.js), de sorte que chaque modification reçoive une nouvelle URL. Envoyez ensuite un an sur ces fichiers.

Fichiers tiers et de plateforme que vous ne pouvez pas modifier

Un éditeur conserve une durée courte sur son script pour pouvoir le mettre à jour sur tous les sites à la fois, et vous ne pouvez pas modifier ses en-têtes. Lighthouse les liste souvent, avec la durée envoyée par leur fournisseur :

  • Meta Pixel (fbevents.js) : 20 minutes
  • Hotjar : 60 secondes
  • L'ancien analytics.js de Google Analytics : 2 heures
  • Google Maps (maps/api/js) : 30 minutes
  • Stripe (js.stripe.com/v3) : 2 minutes
  • Les propres scripts de Cloudflare sur votre domaine (email-decode.min.js, Rocket Loader) : 2 jours

Laissez-les. N'hébergez pas vous-même un loader comme fbevents.js ou gtag.js pour lui attribuer votre propre en-tête : votre copie ne recevrait plus les mises à jour du fournisseur. Ce que vous pouvez faire :

  • Chargez une bibliothèque depuis un CDN public avec une version exacte dans l'URL. jsDelivr donne sept jours à swiper@11 et un an à une version exacte. Ou hébergez vous-même cette version figée, avec votre propre en-tête.
  • Désactivez une fonctionnalité Cloudflare inutile, comme Email Address Obfuscation.
  • Supprimez un tag que plus personne n'utilise.

Quelle durée de cache définir pour quel fichier

  • CSS, JavaScript et polices avec une version ou un hash dans l'URL : un an, avec immutable : Cache-Control: public, max-age=31536000, immutable. Une nouvelle version étant une nouvelle URL, le navigateur la récupère immédiatement.
  • Images : le même en-tête. Donnez un nouveau nom de fichier à une image modifiée, et personne ne verra jamais l'ancienne.
  • CSS, JavaScript et polices sans version : ajoutez-en une d'abord (voir les étapes WordPress et outils de build ci-dessus). En attendant, gardez une durée courte et acceptez que Lighthouse les liste : avec une longue durée sur une feuille de style qui change sous le même nom, les visiteurs qui reviennent reçoivent votre nouveau HTML avec l'ancien CSS.
  • Le HTML : Cache-Control: no-cache ou un max-age court, car avec une longue durée, les visiteurs conserveraient une page obsolète.
  • N'utilisez jamais no-store, no-cache ou must-revalidate sur des fichiers statiques pour faire disparaître l'avertissement, car chaque affichage de page revérifie ou retélécharge alors chaque fichier (voir la page suivante plus haut).

Comment vérifier que vos nouvelles durées de cache fonctionnent ?

Vérifiez d'abord l'en-tête sur le fichier, avec curl ou dans l'onglet Headers (ci-dessus) : il doit afficher le nouveau max-age. Lancez ensuite Lighthouse sur mobile. Il ne liste plus les fichiers, et le score ainsi que les métriques restent identiques, comme dans les quatre rapports plus haut. Sur la page produit, le score oscillait entre 80 et 96 d'un test à l'autre sans aucun lien avec l'en-tête : un score différent après le fix ne vous apprend donc rien sur le cache.

Les visiteurs récurrents dans CoreDash le montrent en premier, en quelques jours, à mesure qu'ils reviennent et reçoivent les fichiers avec leur nouvelle durée. CrUX et Search Console affichent les 28 derniers jours ; deux semaines après le fix, la moitié de ce qu'ils montrent correspond donc toujours à l'ancien site.

Vous avez un doute sur les fichiers listés à corriger, ou vous voulez savoir si vos visiteurs récurrents attendent des fichiers qu'ils possèdent déjà ? Pendant un Core Web Vitals power hour nous passons en revue vos en-têtes et vos field data ensemble, et vous repartez avec les règles pour votre serveur avant de raccrocher.

About the author

Arjen Karel is a web performance consultant and the creator of CoreDash, a Real User Monitoring platform that tracks Core Web Vitals data across hundreds of sites. He also built the Core Web Vitals Visualizer Chrome extension. He has helped clients achieve passing Core Web Vitals scores on over 925,000 mobile URLs.

 

J'écris le code, pas le rapport.

Je m'intègre à votre équipe pendant 1 à 2 sprints. Je branche le monitoring pour que vos métriques restent au vert une fois parti.

Contactez-moi
« Use efficient cache lifetimes » dans Lighthouse : comment le corriger Core Web Vitals « Use efficient cache lifetimes » dans Lighthouse : comment le corriger