Les Core Web Vitals se résument à trois chiffres, et les faire passer au vert bouffe plus de nuits blanches qu'on ne l'avoue. Le Largest Contentful Paint mesure à quelle vitesse ton contenu principal s'affiche. L'Interaction to Next Paint mesure à quelle vitesse la page réagit à un clic ou un tap. Le Cumulative Layout Shift dit si la page reste en place ou gigote pendant le chargement. Google les intègre à son signal Page Experience et les affiche en feu tricolore dans la Search Console, et un mauvais score te coûte cher sur les requêtes concurrentielles en 2026. Voici donc l'ensemble, métrique par métrique : ce que chacune mesure, ce qui la fait bouger, comment la mesurer sans te mentir, et les budgets qui t'évitent de tout reperdre.
The short answer
Les Core Web Vitals sont trois chiffres, tous jugés au 75e percentile des chargements réels sur une fenêtre glissante de 28 jours. LCP sous 2,5 secondes, INP sous 200 millisecondes, CLS sous 0,1. Les trois doivent passer au vert avant que l'URL ne compte comme Good, sans demi-point. Google classe sur les données field (CrUX), pas sur ton ordi portable, alors instrumente tes propres utilisateurs et corrige ce qu'ils ressentent vraiment.
Trois chiffres. Voilà tout ce que sont les Core Web Vitals, et j'ai cramé plus de nuits blanches à les faire passer au vert que je n'oserais l'avouer ici. Le Largest Contentful Paint mesure à quelle vitesse ton contenu principal s'affiche vraiment. L'Interaction to Next Paint mesure à quelle vitesse la page réagit quand quelqu'un clique ou tape. Et puis le Cumulative Layout Shift : est-ce que le tout reste bien en place pendant le chargement, ou est-ce que ça gigote dans tous les sens comme si c'était possédé ? Google les intègre à son signal Page Experience et les affiche sous forme de feu tricolore page par page dans la Search Console. Et oui, en 2026, un mauvais score te coûte cher sur les requêtes concurrentielles. Je l'ai vu de mes yeux. Alors voici l'ensemble, métrique par métrique. Ce que chacune mesure vraiment. Ce qui la fait bouger. Comment la mesurer sans te mentir à toi-même. Quelles corrections tiennent encore la route cette année, et les budgets qui t'évitent de tout reperdre au trimestre suivant.
Pourquoi ces trois chiffres comptent en 2026
Pour être honnête sur le volet classement, et Google l'a dit lui-même : les Core Web Vitals sont un signal, mais un signal faible. La pertinence pèse plus lourd. Un contenu correct et des liens pèsent plus lourd. Si ta page est nulle, tout le vert du monde ne la sauvera pas. Alors pourquoi je continue à courir après le badge ? La performance fait bouger la conversion bien plus fort que le classement. Fais passer une page d'un LCP de 6 secondes à 1,8 seconde et la conversion grimpe en général de 20 à 40 pour cent, et ça se voit bien avant le moindre gain SEO. Il y a aussi une raison plus douce, et je ne vais pas faire comme si elle ne comptait pas : un badge rouge ou vert dans la Search Console met une salle pleine de non-ingénieurs d'accord sur quelque chose. Bon courage pour aligner une équipe marketing autour d'un flame graph à la place.
Les seuils 2026 pour le « Good » : LCP sous 2,5 secondes, INP sous 200 millisecondes, CLS sous 0,1. Chacun est mesuré au 75e percentile des chargements de page réels, par de vrais utilisateurs, sur une fenêtre glissante de 28 jours. Pas ton ordi portable, et pas non plus le Wi-Fi rapide de ton bureau. Et le détail qui piège les gens : les trois doivent être au vert à p75 avant que l'URL ne compte comme Good. Une seule métrique orange et la page entière bascule en « Needs Improvement », sans demi-point.
Mesure lab vs field, et celle sur laquelle Google classe
Deux types de mesure, et ils se contredisent en permanence. Les données lab, c'est le synthétique : Lighthouse, PageSpeed Insights, DevTools, un seul passage contrôlé avec le réseau et le CPU bridés pour simuler un pire cas. Les données field, c'est le réel. Le Chrome User Experience Report (CrUX) les collecte discrètement auprès des vrais utilisateurs de Chrome qui ont accepté, puis les agrège au 75e percentile des 28 derniers jours. Et voilà ce que tu ne dois jamais oublier : Google classe sur les données field. Le lab, c'est parfait pour resserrer la boucle pendant que tu bosses. Mais un Lighthouse vert posé à côté d'un CrUX rouge, c'est sans hésiter la façon la plus courante que j'aie vue une équipe fêter une correction qui n'a jamais touché un seul vrai utilisateur.
Alors comment trancher ? Arrête de deviner et mesure tes propres utilisateurs. Branche la librairie JavaScript web-vitals, envoie les métriques vers ta propre analytique, et tu as une vision page par page dès aujourd'hui au lieu d'attendre un mois que CrUX se mette à jour. Cette boucle de feedback plus courte, c'est tout l'enjeu :
import {onLCP, onINP, onCLS} from 'web-vitals';
function send(metric) {
navigator.sendBeacon('/perf', JSON.stringify(metric));
}
onLCP(send);
onINP(send);
onCLS(send);
Le Largest Contentful Paint (LCP) en détail
Le LCP marque l'instant où ton plus gros élément au-dessus de la ligne de flottaison finit de s'afficher. En général c'est l'image hero ou le bloc de titre, parfois l'image d'aperçu d'une vidéo. Tu vises 2,5 secondes à p75. En pratique, le budget se fait grignoter par un serveur lent à répondre et par les saletés render-blocking coincées entre le HTML et l'affichage. Quand l'élément est une image ou une vidéo, son propre temps de chargement mange ce qui reste. Règle ça et le LCP se débrouille tout seul la plupart du temps.
Temps de réponse du serveur
Le Time to First Byte (TTFB), c'est ton plancher, point barre. Si le TTFB est à 800 ms, ton LCP ne peut physiquement pas descendre sous 800 ms, peu importe l'ingéniosité du reste de ton front end. La solution, c'est le cache, et il est en couches : un cache edge pour les pages statiques, un cache applicatif pour les pages personnalisées, puis un cache de requêtes pour les bouts dynamiques en dessous. Si je ne pouvais faire qu'une seule chose, ce serait le cache HTML au niveau du CDN pour les visiteurs déconnectés. Rien d'autre n'approche ce niveau de levier. Pour les parcours connectés ou personnalisés où le cache devient compliqué, le streaming de réponse via la Streams API laisse le navigateur commencer à mâcher le HTML avant même que ton serveur ait fini de l'écrire.
Ressources render-blocking
Tout ce qui est synchrone dans le head retient ton premier affichage en otage. Chaque fichier CSS. Chaque script bloquant. Ma base de référence 2026, c'est ça : inline le CSS critique et garde-le sous 20 Ko, puis charge la feuille de style principale en non-bloquant avec l'astuce media="print" onload ou rel="preload" as="style". Chaque script part avec defer ou async, ou se fait reléguer à la fin du body. Le tueur de LCP classique sur lequel je trébuche encore tout le temps ? Une page qui balance 100 Ko de CSS répartis sur deux fichiers bloquants, là, en plein dans le head.
Chargement de l'élément LCP
Quand l'élément LCP est une image, quelques détails font la différence. La balise <img> doit vivre dans le HTML. Laisse le JavaScript l'injecter et le navigateur la découvre trop tard, et c'est déjà perdu. Sers-la en AVIF ou WebP, pas en gros vieux JPEG. Puis mets fetchpriority="high" sur la candidate pour que le navigateur sache que c'est la vedette. Encore un, et je le vois sans arrêt : ne colle jamais, au grand jamais, loading="lazy" sur l'image LCP. Cet attribut posé à la légère ajoute à lui seul environ 500 ms dans les mesures de 2026. C'est le genre de bug qui se planque dans un composant partagé et qui sabote discrètement tout un template.
L'Interaction to Next Paint (INP) en détail
L'INP surveille chaque interaction sur la page et remonte la pire. Une interaction étant un clic, un tap, une touche enfoncée, et la latence c'est l'écart entre le déclenchement de cette entrée et l'image suivante qui affiche réellement le résultat à l'écran. Le « Good », c'est 200 ms à p75, et tout ce qui va jusqu'à 500 ms te place en « Needs Improvement ». Il a remplacé le First Input Delay en mars 2024, et franchement ce changement n'était pas trop tôt. Le FID ne chronométrait que la toute première interaction, qui était en général vive même sur une page boursouflée. L'INP attrape la plus lente, et c'est là que la douleur se trouve vraiment.
Neuf fois sur dix, un mauvais INP en 2026 se résume à une seule chose. De longues tâches JavaScript qui monopolisent le main thread dès qu'un utilisateur fait quelque chose. Voici la marche à suivre que je déroule, à peu près par ordre de rentabilité :
- Découpe les longues tâches pour que le navigateur puisse respirer. Glisse un
scheduler.yield()(Chrome 129+) ou unawait new Promise(r => setTimeout(r, 0))entre les gros morceaux et laisse-le afficher. - Déplace les calculs lourds vers un Web Worker et sors-les du main thread une bonne fois pour toutes. Notre guide compagnon explique toute la démarche.
- Reporte les handlers qui n'ont pas besoin d'être instantanés. Quelqu'un clique sur « Ajouter au panier », tu incrémentes d'abord le compteur visible du panier, puis l'appel analytique part un instant plus tard. Ils voient le résultat. La comptabilité peut attendre.
- Mets les scripts tiers en procès. Les widgets de chat et les bannières de consentement sont les suspects habituels, la librairie d'A/B testing aussi. Aucun n'est aussi peu coûteux que le vendeur le jure.
- Profile dans le panneau Performance Insights des DevTools, qui fait remonter des call stacks spécifiques à l'INP depuis Chrome 124. Il te pointe droit sur le handler lent au lieu de te laisser deviner.
Envie de voir ça à l'œuvre pour de vrai ? L'article compagnon sur l'optimisation de l'INP en 2026 fait descendre une page de 480 ms à 120 ms et montre chaque manœuvre qui y a mené.
Le Cumulative Layout Shift (CLS) en détail
Le CLS additionne chaque saut inattendu que vit un utilisateur tant que la page est ouverte. Chaque fois qu'un truc pousse le contenu qu'il s'apprêtait à toucher. Dépasse 0,1 et tu es en « Needs Improvement », dépasse 0,25 et c'est « Poor ». Le mot qui fait tout le travail ici, c'est inattendu : un saut ne compte que s'il n'y a eu aucune interaction utilisateur dans les 500 ms précédentes. Tu cliques sur un truc qui déplie un panneau ou ouvre une modale ? C'est intentionnel, donc exempté. Le calcul de 2026 s'appuie sur une « fenêtre de session », où les sauts espacés de moins d'une seconde sont regroupés en une seule session, et c'est la pire session qui atterrit sur ton bulletin. Ce qui veut dire qu'un seul saut bien méchant peut te couler même quand le reste du chargement est lisse comme du verre.
Les quatre sources courantes de CLS
- Images et iframes sans dimensions. Le navigateur ne peut pas deviner leur taille, alors il ne réserve rien, et quand elles finissent par charger, tout ce qui est en dessous dégringole. Mets
widthetheight, ou appuie-toi sur le CSS aspect-ratio pour les responsives. Gratuit à corriger, et j'en trouve encore partout. - Polices web qui font reflow le texte.
font-display: swapaffiche d'abord une police de repli puis bascule sur ta police web, et si les métriques ne collent pas, ton texte se redimensionne et se réenroule en pleine lecture. Pour tout ce qui est au-dessus de la ligne de flottaison, je sorsfont-display: optional, ou je précharge la police avecrel="preload"pour que le swap ne se voie jamais. - Trucs injectés au-dessus de ce qui est déjà là. Le coupable d'école, c'est une bannière cookies qui débarque à 800 ms et pousse toute la page vers le bas. Épingle-la en bas du viewport en positionnement absolu, ou réserve son espace dans le HTML initial pour que rien n'ait à bouger.
- Animer les mauvaises propriétés. Touche à
heightoutopet le navigateur relance le layout à chaque image. Anime plutôttransformetopacity, puisque le compositeur les gère sans rien déranger autour.
Budgets de performance et garde-fous CI
Voilà ce dont personne ne te prévient : sans budget, toutes les équipes régressent. Je n'ai encore jamais vu d'exception. Le plus petit budget qui vaille le coup épingle deux chiffres dans la CI, ton bundle JavaScript sous 200 Ko compressés par route et un score de performance Lighthouse au-dessus de 90 en staging. Branche bundlewatch et size-limit aux côtés de Lighthouse CI dans GitHub Actions, et ils refuseront tout bonnement la PR à la seconde où l'un des deux dérape. Dire non à une fonctionnalité de 10 Ko semble mesquin sur le moment. Mais dis-lui oui dix fois d'affilée, et tu te réveilles avec un bundle de 2 Mo et aucune idée d'où il sort.
Une fois que ça tient, empile un deuxième étage par-dessus : des alertes sur données field. Branche tes chiffres web-vitals sur Slack ou PagerDuty pour être pingé à la seconde où le p75 de LCP, INP ou CLS sort du vert sur les dernières 24 heures. La CI ne les attrape jamais, parce qu'ils ne surviennent pas au build. Ils surviennent quand quelqu'un au marketing uploade une image hero de 5 Mo à 16 h un vendredi et part pour le week-end, et que le build est resté vert tout du long.
Un workflow Core Web Vitals hebdomadaire
Le rythme dans lequel je me suis installé pour 2026 est tout bête. Lundi, tu tires les chiffres CrUX sur 28 jours depuis la Search Console, tu les compares à la semaine dernière, tu signales tout ce qui a dérivé dans le mauvais sens. Mardi, tu lances Lighthouse sur tes 20 pages les plus visitées en staging et tu vérifies que les chiffres lab collent à ce que tu attendrais. Et non, la fenêtre de déploiement des corrections de perf, ce n'est pas le vendredi après-midi. Livre-les en début de semaine et elles ont plusieurs jours pour cracher une régression avant que tout le monde débauche. Rien d'extraordinaire. Ça attrape juste les problèmes tant qu'ils sont encore petits.
Et laisse tomber l'idée que la performance serait un coup d'éclat héroïque ponctuel. Ce n'en est pas un. Une ou deux petites victoires par semaine (un script reporté par-ci, une image compressée par-là, de l'espace réservé pour cette bannière) finissent par s'additionner en quelque chose de réel. Bien plus sûrement que le redouté « sprint performance » trimestriel qui bouffe deux semaines et épuise tout le monde. Bizarrement, celui-là ne se retrouve plus jamais au calendrier.
Les erreurs courantes qui bloquent les progrès
- Courir après le chiffre Lighthouse au lieu de CrUX. Tu peux rester planté là avec un suffisant 95 en lab pendant que ton p75 field saigne au rouge. Corrige ce que tes vrais utilisateurs ressentent, pas ce que ton ordi portable te renvoie.
- Croire que le LCP, c'est juste l'image. Le plus souvent les dégâts viennent du serveur, ou du CSS render-blocking, ou des polices. L'image, c'est ce que tu regardes ramer. C'est rarement la vraie cause.
- Boulonner un outil tiers pour « régler » la performance. Chacun d'eux embarque plus de code, et j'en ai vu un paquet coûter plus qu'ils n'ont jamais rapporté. Lis l'onglet réseau avant d'acheter le discours commercial.
- Faire l'impasse sur ta propre instrumentation field. Attendre 28 jours que CrUX te dise si une correction a marché, c'est à peu près la boucle de feedback la plus lente qui soit. Livre
web-vitalsd'abord et tu sauras dès demain. - Optimiser une métrique en isolation. Inline 200 Ko de CSS pour sauver le LCP et tu vas discrètement saccager l'INP et le FCP au passage. Elles bougent ensemble. Traite les trois comme un seul système, ou tu joueras au tape-taupe pour l'éternité.
Questions fréquentes
Combien de temps après un déploiement la Search Console reflète-t-elle le changement ?
Plus lentement que tu ne le voudrais. CrUX fait la moyenne sur une fenêtre glissante de 28 jours, donc un seul déploiement bouge à peine le chiffre field au début. Sur une page à fort trafic, tu attraperas en général le premier delta autour du 7e jour, et le tableau complet arrive à 28 jours. Tu ne peux pas attendre aussi longtemps ? Honnêtement, personne ne peut. Instrumente avec web-vitals et surveille ta propre analytique, et tu verras le changement en moins de 24 heures.
Mobile et desktop ont-ils des seuils différents ?
Les seuils sont identiques (LCP 2,5 s, INP 200 ms, CLS 0,1) sur les deux. Mais la Search Console les reporte et les classe séparément, donc tu verras régulièrement une page rester verte en desktop et orange en mobile. Et c'est presque toujours le mobile qui force la correction, parce que le mobile, c'est là que vivent vraiment le matériel lent et les réseaux capricieux.
Mon élément LCP change tout le temps, comment l'optimiser ?
Exact, parce que le LCP, c'est ce qui est le plus gros à l'instant de la mesure, et différentes variantes d'une page peuvent couronner des gagnants différents. Alors arrête de deviner. Utilise l'API LCP pour logguer quel élément est retenu à chaque chargement, puis regroupe les résultats par motif d'URL. Optimise celui qui gagne le plus souvent pour chaque motif, et passe à autre chose. Cette longue traîne de bizarreries représente en général moins de 5 pour cent des chargements. Pas de quoi en perdre le sommeil.
Devrais-je viser le score parfait ?
Non, et s'il te plaît, n'en fais rien. Atteins les seuils Good à p75, puis tourne les talons. Passer du vert à un 100 parfait coûte une fortune en temps d'ingénierie et ne te rapporte quasiment rien au classement. Dépense ces heures sur du contenu ou des fonctionnalités que tes utilisateurs remarqueront vraiment.
Et l'INP pour les applications gourmandes en saisie comme les éditeurs de texte ?
Ouais, les éditeurs sont le cas vraiment dur, parce que chaque touche enfoncée compte comme une interaction. L'astuce, c'est de garder le travail synchrone par frappe minuscule, sous 16 ms, pour que l'image arrive toujours à l'heure. Regroupe la coloration syntaxique et la tenue de l'arbre d'annulation avec requestIdleCallback, puis pousse tout ce qui est lourd comme l'autosave ou la synchro collaborative dans un Web Worker. C'est le pattern derrière des éditeurs comme Notion et Linear, et c'est comme ça qu'ils tiennent l'INP sous 100 ms à p75 pendant que tu martèles le clavier.