Des 3 indicateurs qui composent les Core Web Vitals, le Largest Contentful Paint (LCP) est celui qui parle le plus directement à vos utilisateurs : c’est lui qui traduit le sentiment « la page s’est affichée ». C’est aussi, paradoxalement, le plus mal optimisé. Le conseil que l’on croise partout, « compressez vos images », n’est pas faux, mais il passe à côté de l’essentiel dans une large majorité de cas.
Dans cet article, nous décomposons le LCP comme le font nos experts au quotidien : non pas comme un chiffre unique à faire baisser, mais comme une chaîne de quatre étapes dont chaque maillon se diagnostique et s’optimise séparément. Données terrain de Google à l’appui, vous comprendrez pourquoi le vrai gisement de performance se situe presque toujours ailleurs que là où on le cherche, et repartirez avec une méthode d’optimisation complète, du serveur jusqu’au pixel.
Le LCP, qu’est-ce que c’est exactement ?
Le Largest Contentful Paint mesure le temps écoulé entre le début de la navigation (le clic sur un lien, la saisie d’une URL) et le moment où le plus grand élément de contenu visible dans la fenêtre d’affichage, le viewport, est rendu à l’écran. L’idée sous-jacente est simple : l’élément le plus imposant est, la plupart du temps, celui que l’internaute attend pour considérer que quelque chose s’est réellement passé.
Cet élément candidat au titre de LCP appartient généralement à l’une de ces catégories :
- une balise
<img>, le cas le plus fréquent (typiquement une image de couverture ou hero) ; - une image chargée via
background-imageen CSS ; - l’affiche (poster) d’une balise
<video>; - depuis août 2023, une vidéo ou une image animée peut elle-même être retenue comme élément LCP, d’après le changelog officiel de Chromium ; un site à bannière vidéo est donc directement concerné ;
- un bloc de texte de niveau bloc (un titre, un paragraphe) rendu avec sa police d’écriture.
Pour offrir une bonne expérience, Google fixe un objectif clair : un LCP inférieur ou égal à 2,5 secondes pour au moins 75 % des visites. Au-delà de 4 secondes, il est jugé mauvais ; entre les deux, il reste à améliorer.
Cette précision du « 75e centile » est capitale. Le LCP qui compte pour votre référencement n’est pas celui que vous mesurez depuis votre ordinateur sur une connexion fibre, mais celui que vivent vos utilisateurs réels, consolidé par Google dans le Chrome User Experience Report (CrUX). Un test synthétique Lighthouse ou PageSpeed Insights reste un excellent outil de diagnostic, mais c’est la donnée terrain qui fait foi. Nous y reviendrons en détail.
À noter : la définition même du LCP a été affinée au fil du temps pour mieux coller à la perception. Comme l’analyse Tim Kadlec dans The growing contentful gap, le calcul du LCP a évolué pour écarter certains éléments non significatifs (images de très faible contenu, placeholders), ce qui creuse l’écart avec le First Contentful Paint mais rend la métrique plus représentative de l’instant où l’utilisateur voit vraiment le contenu principal.
Une métrique unique qui cache une chaîne de dépendances
La grande difficulté du LCP, c’est qu’il agrège des phénomènes de natures très différentes : du temps serveur, du temps réseau, du temps de calcul navigateur. Optimiser « le LCP » dans l’absolu n’a pas de sens. En revanche, on peut le décomposer en quatre sous-parties consécutives, sans chevauchement ni interstice, dont la somme reconstitue exactement la métrique. Cette grille de lecture est celle du guide de référence Optimize LCP de web.dev.
- TTFB (Time To First Byte) : le temps entre la navigation et la réception du premier octet du document HTML. Il englobe la résolution DNS, l’établissement de la connexion et le temps de traitement serveur.
- Délai de chargement de la ressource (resource load delay) : le temps entre le TTFB et le moment où le navigateur commence à télécharger la ressource LCP. Si l’élément LCP est un texte rendu avec une police système, ce délai est nul.
- Durée de chargement de la ressource (resource load duration) : la durée de téléchargement de la ressource LCP elle-même (l’image, le plus souvent).
- Délai de rendu de l’élément (element render delay) : le temps entre la fin du téléchargement de la ressource et son affichage effectif à l’écran.
Ce découpage n’est pas qu’un exercice théorique : il change radicalement la façon d’optimiser. Prenons un exemple qui piège la plupart des intervenants. Vous identifiez une image LCP un peu lourde, vous la recompressez en AVIF, vous divisez son poids par trois. La durée de chargement chute, mais le LCP ne bouge pas d’un millimètre. Pourquoi ? Parce que sur cette page, l’image était en réalité masquée par du JavaScript jusqu’à son exécution complète : le temps gagné sur le téléchargement s’est simplement déplacé vers le délai de rendu. La photographie est prête plus tôt, mais elle attend toujours le même feu vert pour s’afficher.
C’est toute la valeur de l’approche par sous-parties : elle vous dit où agir, et vous évite d’investir de l’énergie sur un maillon qui n’est pas le goulet d’étranglement. Sur une page bien optimisée, la répartition idéale ressemble à ceci :
- TTFB : environ 40 % du LCP ;
- Délai de chargement : moins de 10 % ;
- Durée de chargement : environ 40 % ;
- Délai de rendu : moins de 10 %.
La logique est limpide : les deux sous-parties qui portent le mot « délai » sont des temps morts, à ramener aussi près de zéro que possible. L’essentiel du LCP devrait être consacré à ce qui est incompressible : livrer le HTML, puis télécharger la ressource. Tout instant où ni l’un ni l’autre n’est en cours de chargement est une opportunité d’optimisation.
Ce que révèle la donnée terrain (et qui va à contre-courant)
Lorsque les équipes de Chrome ont analysé les sous-parties du LCP sur des millions de sites réels, le résultat a surpris jusqu’aux spécialistes. Le conseil historique, « réduisez le poids de vos images », ne correspond tout simplement pas à l’endroit où le temps se perd. Cette étude est détaillée dans Common misconceptions about how to optimize LCP.
La lecture de ce graphique est édifiante. Chez les sites au LCP mauvais, la durée de téléchargement de l’image (350 ms) est la plus courte des quatre sous-parties. Ce sont le TTFB (2 270 ms) et le délai de chargement (1 290 ms) qui font exploser la métrique. Autrement dit : la majorité des sites en difficulté passent moins de 10 % de leur temps de LCP à télécharger l’image incriminée.
Le chiffre le plus parlant concerne le délai de chargement, ce temps mort trop souvent ignoré : un site au LCP mauvais attend en médiane 1,3 seconde entre la réception du HTML et le début du téléchargement de l’image, soit près de quatre fois plus longtemps que le téléchargement lui-même. Plus de la moitié du budget de 2,5 secondes est consumée avant même que le navigateur ne commence à récupérer l’élément principal de la page.
La cause ? Presque toujours des chaînes de dépendances. L’image LCP n’est pas déclarée directement dans le HTML : elle est fixée par une feuille de style qui doit d’abord se télécharger, ou injectée par un script qui doit d’abord s’exécuter. Chaque maillon supplémentaire dans cette chaîne repousse d’autant le moment de la découverte. La donnée d’HTTP Archive le confirme sans ambiguïté : le LCP médian passe de 2,15 s sans requête intermédiaire, à 2,54 s avec une, puis 2,85 s avec deux.
Dernier mythe balayé par les chiffres : le mobile ne serait pas le coupable qu’on imagine. Pour la durée de téléchargement de l’image, un mobile n’est en médiane que 20 % plus lent qu’un ordinateur de bureau. La qualité des réseaux mobiles n’est plus l’alibi qu’elle était. Le vrai combat se joue sur l’architecture de chargement, pas sur le poids des octets.
Optimiser le LCP, sous-partie par sous-partie
Fort de ce diagnostic, voici comment nos experts interviennent, dans l’ordre où l’impact est généralement le plus fort. L’objectif directeur ne varie jamais : faire en sorte que la ressource LCP commence à se charger le plus tôt possible et s’affiche immédiatement une fois téléchargée.
1. Éliminer le délai de chargement : le gisement oublié
C’est, la donnée l’a montré, le levier le plus rentable. La règle d’or : votre ressource LCP doit commencer à se télécharger en même temps que la toute première ressource de la page. Si elle démarre plus tard, il y a du temps à récupérer.
Premier réflexe : rendre l’image découvrable par le preload scanner, ce composant du navigateur qui inspecte le HTML brut avant même la construction du rendu pour anticiper les téléchargements. Une image LCP dont le src (ou le srcset) est présent directement dans le HTML est découverte instantanément. À l’inverse, une image injectée en JavaScript ou masquée derrière un attribut data-src de lazy-loading reste invisible jusqu’à l’exécution du script : c’est exactement le délai que l’on cherche à supprimer.
On signale ensuite explicitement au navigateur l’importance de la ressource grâce à l’attribut fetchpriority (disponible sur Chrome 102+, Safari 17.2+ et Firefox 132+). Par défaut, le navigateur charge une image en priorité basse, le temps de calculer son rôle dans la mise en page : fetchpriority="high" la promeut immédiatement.
<!-- Image LCP directement dans le HTML, priorité haute -->
<img src="/img/hero.avif" fetchpriority="high"
width="1600" height="900" alt="Description pertinente">
L’ampleur du gain n’est pas anecdotique : de 5 à 30 % sur le LCP selon la stack, avec une moyenne autour de 15 %, d’après les mesures d’Addy Osmani (Chrome) dans son analyse dédiée. Trois pièges d’expert à connaître, cependant :
- un
fetchpriority="high"ne doit être posé que sur une seule image, deux au maximum : le distribuer sur dix ressources revient à ne rien prioriser, et le navigateur retombe sur son heuristique par défaut ; - le
fetchpriorityne s’applique pas aux images de fond CSS, que le preload scanner ne voit pas non plus : si votre LCP est unbackground-image, convertissez-le en<img>ou<picture>; - la combinaison
loading="lazy"etfetchpriority="high"est cassée : le lazy-loading retire toujours la priorité. Ne mettez jamais votre image LCP en lazy.
À l’inverse, on peut dé-prioriser (fetchpriority="low") les images hors écran, comme les diapositives non visibles d’un carrousel, pour libérer de la bande passante au profit du LCP. Enfin, si l’image LCP ne peut être qu’une image de fond, on la précharge depuis le HTML pour la révéler au plus tôt :
<link rel="preload" as="image" href="/img/hero.avif"
type="image/avif" fetchpriority="high">
2. Mettre le en ordre : la méthode CAPO
Voici un levier que 90 % des sites négligent, et qui agit directement sur le délai de chargement : l’ordre des balises dans le <head>. Le preload scanner lit le <head> de façon linéaire. Une balise <script> synchrone placée avant un <link rel="preconnect"> retarde l’ouverture de la connexion vers votre CDN d’images : la connexion n’est établie qu’une fois le script exécuté. Autant de millisecondes perdues avant même de découvrir la ressource LCP.
La méthode CAPO (Critical Above Paint Order), formalisée par Rick Viscomi de HTTP Archive dans Get your head in order, propose un classement strict, du plus prioritaire au moins prioritaire : d’abord meta charset (qui doit figurer dans les 1024 premiers octets du document) et <title>, puis les preconnect et les feuilles de style critiques, et seulement ensuite les scripts, les prefetch et les métadonnées SEO ou Open Graph. Ordonner le <head> une fois pour toutes dans le template, c’est offrir au navigateur le chemin le plus court vers vos ressources critiques.
Dans le même esprit, les resource hints méritent d’être maniés avec précision plutôt que dispersés :
- un
preconnectvers un domaine de polices ou un CDN en CORS exige l’attributcrossorigin: sans lui, la connexion TLS établie n’est pas réutilisée et une nouvelle connexion est rouverte, annulant le bénéfice ; - limitez-vous à trois ou quatre
preconnect: chaque connexion anticipée a un coût, et au-delà le navigateur ignore les suivantes ; - traquez les preloads orphelins : un
<link rel="preload" as="image">qui pointe vers une image que la page n’utilise plus (héritage fréquent d’un ancien design) déclenche un téléchargement gaspillé, et Chrome le signale en console.
3. Supprimer le délai de rendu
Une fois la ressource téléchargée, elle doit s’afficher sans attendre. Or plusieurs coupables retardent fréquemment ce rendu :
- des feuilles de style ou des scripts synchrones dans le
<head>qui bloquent le rendu de toute la page tant qu’ils ne sont pas chargés ; - un élément LCP encore absent du DOM, en attente d’un JavaScript pour être injecté ;
- un outil d’A/B testing qui masque le contenu le temps de décider quelle variante afficher ;
- des long tasks qui monopolisent le fil principal, le rendu des images s’y effectuant lui aussi.
La parade la plus efficace consiste à alléger le chemin de rendu critique. Aucun script synchrone ne devrait figurer dans le <head> : on lui préfère defer (ou async quand l’ordre importe peu), en le basculant même idéalement en fin de corps plutôt que dans l’en-tête.
<!-- À éviter : bloque le rendu -->
<head><script src="/js/app.js"></script></head>
<!-- À privilégier : n'interrompt pas l'affichage -->
<body>(...)<script src="/js/app.js" defer></body></head>
Sur ce terrain, le rendu côté serveur (SSR) ou la génération statique (SSG) offrent un avantage décisif : le contenu, image LCP comprise, est présent dès le HTML, sans dépendre du téléchargement puis de l’exécution d’un bundle JavaScript. C’est l’une des raisons pour lesquelles les sites en pur rendu côté client peinent structurellement sur le LCP. Sur ce sujet précis, notre expertise dédiée aux Single Page Applications permet de lever les blocages propres aux frameworks modernes.
4. Réduire la durée de chargement de la ressource
La donnée l’a rappelé : ce n’est généralement pas ici que se joue votre LCP. Mais servir des octets superflus reste une faute, et sur certains sites l’image est réellement le facteur limitant. Le premier levier est le format. La hiérarchie de préférence est aujourd’hui claire : l’AVIF d’abord (environ 50 % plus léger que le JPEG, 20 % de moins que le WebP), le WebP en repli, le JPEG en dernier recours via une balise <picture>. Attention toutefois : le WebP n’est pas systématiquement meilleur, comme le rappelle web.dev ; sur une image déjà bien compressée, la conversion peut alourdir le fichier, et l’AVIF a un coût de décodage plus élevé. Un pipeline d’images intelligent ne convertit que si le gain est réel.
Viennent ensuite les fondamentaux :
- servir la bonne taille via
srcsetetsizes, pour ne jamais livrer une image de 2000 px à un écran mobile ; - renseigner les dimensions explicites (
widthetheight) : elles évitent les décalages de mise en page (CLS) et aident le navigateur à réserver l’espace au plus tôt ; - rapprocher la ressource de l’utilisateur avec un CDN d’images, qui optimise souvent le format à la volée ;
- supprimer purement le réseau pour les visiteurs récurrents grâce à une politique de cache
Cache-Controlefficace.
<img src="/img/hero-800.avif"
srcset="/img/hero-400.avif 400w,
/img/hero-800.avif 800w,
/img/hero-1600.avif 1600w"
sizes="(max-width: 600px) 100vw, 800px"
fetchpriority="high" width="800" height="450" alt="…">
Un mot sur les images de substitution (LQIP, pour Low Quality Image Placeholder). L’expert Harry Roberts détaille dans The ultimate LQIP/LCP technique une nuance capitale : un placeholder mal implémenté, révélé par JavaScript, peut retarder l’affichage de la vraie image ou brouiller la mesure du LCP. La bonne approche laisse l’image finale rester l’élément LCP, et réserve le placeholder à un effet visuel léger qui ne bloque rien. Enfin, si votre ressource LCP est une police d’écriture (cas d’un titre en webfont), une valeur font-display: swap affiche le texte immédiatement avec une police de repli, puis l’échange sans bloquer le LCP.
5. Réduire le TTFB
Placé en dernier car c’est souvent celui sur lequel on a le moins la main côté front-end, le TTFB n’en reste pas moins fondateur : rien ne peut se produire côté navigateur tant que le serveur n’a pas livré son premier octet. Chaque milliseconde gagnée ici se répercute mécaniquement sur toutes les étapes suivantes. C’est d’ailleurs ce que confirme la donnée terrain : chez les sites lents, le seul TTFB (2 270 ms au 75e centile) suffit presque à condamner l’objectif de 2,5 secondes.
Les causes classiques d’un TTFB élevé : des redirections en cascade (fréquentes derrière des liens publicitaires ou raccourcis), une absence de cache HTML qui force la régénération de chaque page, ou des requêtes qui contournent le cache du CDN à cause de paramètres d’URL inutiles. La réponse passe par un cache serveur solide, une infrastructure géolocalisée au plus près des visiteurs et une configuration réseau maîtrisée, le socle même de notre offre d’hébergement performant.
Le bonus : le bfcache, un LCP quasi nul
Il existe un cas où le LCP tombe à quelques millisecondes : la navigation via les boutons précédent et suivant du navigateur, servie par le Back/Forward Cache (bfcache). Ce mécanisme conserve en mémoire un instantané complet de la page déjà visitée : au retour, elle réapparaît instantanément, sans nouveau chargement ni nouveau rendu. Les navigations restaurées depuis le bfcache rapportent un LCP quasi nul, ce qui améliore vos métriques terrain agrégées.
Encore faut-il ne pas s’en priver involontairement. Certaines pratiques désactivent le bfcache : un en-tête Cache-Control: no-store, la présence d’un gestionnaire d’événement unload, ou certaines connexions ouvertes non fermées. Le panneau Application de Chrome DevTools propose un test dédié qui liste précisément les raisons de non-éligibilité. Un audit rigoureux inclut systématiquement cette vérification, souvent gratuite en gains.
Mesurer avant d’optimiser, toujours
Un principe guide toute notre méthodologie : on n’optimise pas à l’aveugle. Avant de toucher à quoi que ce soit, il faut savoir quelle sous-partie pèse sur votre LCP, sur vos données réelles. Une optimisation pertinente sur un site peut être parfaitement inutile sur un autre : c’est tout l’intérêt du diagnostic par sous-parties.
Concrètement, on croise trois sources. D’abord la donnée terrain (CrUX via PageSpeed Insights ou la Search Console, complétée par du RUM pour les pages à faible trafic). Bonne nouvelle pour le diagnostic : depuis février 2025, le CrUX expose désormais les sous-parties de l’image LCP et le temps d’aller-retour réseau, là où il fallait auparavant se rabattre sur le laboratoire. Ensuite les outils de laboratoire (Lighthouse et le panneau Performance de Chrome DevTools, qui affichent le détail des quatre sous-parties). Enfin, pour un suivi continu, l’API PerformanceObserver :
new PerformanceObserver((list) => {
const entries = list.getEntries();
const lcp = entries[entries.length - 1];
console.log('LCP :', Math.round(lcp.startTime), 'ms');
console.log('Élément :', lcp.element);
}).observe({ type: 'largest-contentful-paint', buffered: true });
Pour aller plus loin, la bibliothèque web-vitals de Google, dans sa variante « attribution », calcule automatiquement le découpage en quatre sous-parties : c’est l’outil idéal pour transformer un LCP abstrait en plan d’action concret, directement sur vos utilisateurs réels.
En résumé
Le LCP n’est pas une affaire d’images à compresser : c’est une chaîne de chargement à orchestrer. Retenez la démarche en quatre temps que suivent nos experts :
- faire découvrir et démarrer la ressource LCP le plus tôt possible (HTML propre, preload scanner,
fetchpriority,<head>en ordre CAPO) ; - garantir son affichage immédiat une fois téléchargée (rendu non bloqué, SSR/SSG, fil principal libre) ;
- réduire sa durée de téléchargement sans sacrifier la qualité (AVIF, images responsive, CDN, cache) ;
- livrer le HTML initial au plus vite (TTFB, cache serveur, zéro redirection superflue).
Cette lecture par sous-parties, adossée à la donnée terrain, est précisément ce qui distingue une optimisation qui déplace le problème d’une optimisation qui le résout. C’est le cœur de notre métier : si votre LCP résiste malgré vos efforts, nos experts en optimisation de la web performance identifient le maillon fautif et le corrigent durablement. Un audit reste souvent le meilleur point de départ pour objectiver vos marges de progression, chiffres à l’appui.