SEOGuide

Core Web Vitals 2026 : corriger LCP, INP et CLS

Sur cette page
  1. Les seuils « Good » de 2026 et où Google les mesure
  2. LCP : code avant/après et optimisations
  3. INP : code avant/après et optimisations
  4. CLS : code avant/après et optimisations
  5. Optimisations spécifiques à WordPress
  6. Optimisations spécifiques à Cloudflare
  7. Lire correctement une capture Lighthouse
  8. Sources et lectures complémentaires

Les Core Web Vitals en 2026 se resument a trois lettres qui decident si Google trouve que tes pages donnent une impression de rapidite : LCP (Largest Contentful Paint), INP (Interaction to Next Paint), CLS (Cumulative Layout Shift). Elles font bouger ton classement sur les requetes que tout le monde s'arrache, et elles decident si un visiteur reste assez longtemps pour convertir au lieu de fuir, ecoeure. Donc ici, je te parle de ce que j'ai vraiment mis en prod, pas de theorie. Chaque metrique a droit a son extrait avant/apres que j'ai fait tourner en production, je te montre comment je lis une capture Lighthouse, plus les reglages WordPress et Cloudflare qui m'ont rapporte les plus gros gains.

The short answer

Les Core Web Vitals recompensent les donnees terrain, pas ton ordinateur portable. Les trois (LCP, INP, CLS) doivent passer au vert ensemble, au 75e percentile, sur 28 jours glissants de vrais utilisateurs Chrome (CrUX). Les gains les plus rapides viennent d'un cache de page, d'un hero AVIF avec fetchpriority="high" et sans loading="lazy", du travail debounce deplace dans un Web Worker, et de width/height sur chaque image. Lighthouse sert a iterer ; c'est la "Page Experience" de la Search Console qui te classe vraiment.

< 2,5 sLCP au p75
< 200 msINP au p75
< 0,1CLS au p75
Carte reponse : LCP sous 2,5 s, INP sous 200 ms, CLS sous 0,1, le tout juge au 75e percentile des vraies donnees terrain dans CrUX.
Toute la barre : trois metriques, toutes au vert au p75 sur 28 jours, sinon l'URL n'est pas Good. PNG

Trois lettres. Elles décident si Google trouve que mes pages donnent une impression de rapidité, et elles m'ont coûté plus de nuits de sommeil que je n'oserais l'avouer à voix haute : LCP (Largest Contentful Paint), INP (Interaction to Next Paint), CLS (Cumulative Layout Shift). Ensemble, ce sont les Core Web Vitals. En 2026, elles font bouger ton classement sur les requêtes que tout le monde s'arrache, et elles décident aussi si un visiteur reste assez longtemps pour convertir au lieu de fuir, écœuré. Donc ici, je te parle de ce que j'ai vraiment mis en prod, pas de théorie. Chaque métrique a droit à son extrait avant/après que j'ai fait tourner en production, je te montre comment je lis une capture Lighthouse sans me mentir à moi-même, plus les réglages WordPress et Cloudflare qui m'ont rapporté les plus gros gains, ceux vers lesquels je me tourne en premier.

Les seuils « Good » de 2026 et où Google les mesure

C'est là que les gens trébuchent. Tu ne décroches pas le badge « Good » en cartonnant sur une seule métrique. Les trois doivent passer ensemble, au 75e percentile, sur 28 jours glissants de vraies données terrain (CrUX). Les chiffres n'ont pas bougé depuis 2024 : LCP < 2,5 s, INP < 200 ms, CLS < 0,1. Rate-les et tu tombes en « Needs Improvement » jusqu'à LCP 4 s, INP 500 ms, CLS 0,25. Au-delà ? Rouge.

Et celle-là m'a coûté une semaine entière au début. Google te classe sur les données terrain des utilisateurs Chrome qui ont opté pour le partage, pas sur ce que Lighthouse te murmure en local. Lighthouse est vraiment utile pendant que tu itères. Mais un beau Lighthouse à 95 assis à côté d'un p75 à 4 secondes dans CrUX, c'est le piège qui attrape absolument tout le monde, moi y compris. Tu chronomètres ta fibre 1 Gbps sur un MacBook M3. Ton visiteur, lui, est sur un Android à bout de souffle en 4G dans un tunnel de métro. Crois le rapport « Page Experience » de la Search Console et tes propres chiffres web-vitals côté client. Rien d'autre n'a voix au chapitre.

Comparaison des seuils des Core Web Vitals 2026 au 75e percentile : LCP Good a 2,5 s, INP Good a 200 ms et Poor au-dela de 500 ms, CLS Good a 0,1 et Poor au-dela de 0,25.
La ou chaque metrique bascule de Good a Poor, ramene sur un seul axe. L'INP et le CLS portent chacun une large bande orange avant l'echec plat. PNG

LCP : code avant/après et optimisations

Le LCP, c'est un chrono. Il s'arrête à l'instant où ton plus gros élément au-dessus de la ligne de flottaison finit de s'afficher, en général l'image hero, parfois un bloc de titre ou une frame de vidéo. Au fond, il n'y a que quelques leviers qui valent la peine, et le TTFB serveur est le plus gros. Ensuite, ce qui bloque le rendu dans le <head>, et le temps que l'élément LCP lui-même met à apparaître. Soigne ça et le reste compte à peine.

Cas 1 : image hero lazy-loadée par erreur

Celle-là, je l'ai mise en prod par accident. Plus d'une fois, ce qui est gênant. Un plugin de hero colle loading="lazy" sur toutes les images qu'il croise, y compris celle-là même qui définit ton LCP. Du coup le navigateur hausse les épaules, la découvre beaucoup trop tard, et bam, te voilà au-delà de 4 s à te demander ce qui s'est passé.

Before, LCP 4.2 s

<img src="/uploads/hero.jpg"
     loading="lazy"
     width="1200" height="600"
     alt="Hero image">

After, LCP 1.7 s

<img src="/uploads/hero.avif"
     fetchpriority="high"
     width="1200" height="600"
     alt="Hero image">
<!-- no loading="lazy" on the LCP image -->

Associe fetchpriority="high" à une source AVIF (garde un fallback WebP, certains vieux navigateurs en ont encore besoin) et tu récupéreras en général 1,5 à 2 s rien que sur le hero. Mais ne sois pas gourmand. Vire loading="lazy" de cette seule image, celle-ci, et laisse-le sur tout ce qui est sous la ligne de flottaison. Lazy-loader le reste, c'est toujours la bonne approche.

Cas 2 : police web qui bloque le rendu

Tu récupères une police sur Google Fonts avec un simple <link rel="stylesheet">, tu te dis que c'est bon, tu passes à autre chose. Sauf que ce link bloque le rendu. Le navigateur reste planté là à se tourner les pouces, à attendre le fichier de police avant d'afficher ne serait-ce qu'un seul mot de ton titre. Ton LCP texte avale tout le délai.

Before, LCP 3.4 s

<link href="https://fonts.googleapis.com/
  css2?family=Inter:wght@400;700"
  rel="stylesheet">

After, LCP 1.9 s

<link rel="preconnect"
  href="https://fonts.gstatic.com" crossorigin>
<link rel="preload"
  href="/fonts/inter-700.woff2"
  as="font" type="font/woff2" crossorigin>
<style>
  @font-face{font-family:Inter;
    font-display:swap;
    src:url(/fonts/inter-700.woff2)
        format('woff2');}
</style>

Quelques petits gestes font tout le boulot. Auto-héberge le fichier, ce qui supprime un aller-retour complet vers fonts.googleapis.com. Ajoute font-display: swap pour que le texte s'affiche dans une police de secours pendant que la vraie rattrape son retard. Puis précharge uniquement la graisse qui apparaît réellement au-dessus de la ligne de flottaison, pas toute la famille. Ce combo m'a fait gagner 1 à 1,5 s de LCP texte, de façon assez fiable.

INP : code avant/après et optimisations

L'INP punit ton pire moment, pas ta moyenne. Il retient l'interaction la plus lente sur toute la vie de la page, donc un seul clic qui rame 800 ms te bascule en orange même quand chaque autre tap répond du tac au tac en 50 ms. Tu ne peux pas enfouir une mauvaise interaction sous un millier de bonnes. Ça ne marche pas comme ça, et franchement il m'a fallu un moment pour faire la paix avec ça.

Cas 3 : longue tâche synchrone qui bloque l'UI

Voilà un classique sur lequel je n'arrête pas de buter en vrai. Un filtre côté client qui boucle sur 8 000 éléments et re-render à chaque frappe au clavier. Ça fait 600 ms de thread principal gelé par caractère tapé, et l'utilisateur sent chaque misérable milliseconde.

Before, INP 620 ms

input.addEventListener('input', (e) => {
  const q = e.target.value.toLowerCase();
  const filtered = items.filter(item =>
    item.name.toLowerCase().includes(q)
  );
  render(filtered); // blocks 620ms
});

After, INP 95 ms

let timer;
input.addEventListener('input', (e) => {
  clearTimeout(timer);
  const q = e.target.value.toLowerCase();
  timer = setTimeout(async () => {
    const filtered = await runInWorker(items, q);
    render(filtered);
  }, 80); // debounce + Worker
});

Deux gestes portent le correctif. Le debounce, pour arrêter de tout recalculer à chaque frappe. Puis pousser la boucle lourde dans un Web Worker, ce qui laisse le thread principal libre de répondre à l'utilisateur. Et si un Worker complet représente plus de boulot que tu ne peux encaisser là maintenant (je comprends, parfois c'est la deadline qui gagne), saupoudre scheduler.yield() entre les morceaux pour que le navigateur ait une chance de respirer. Je creuse le côté Worker dans notre guide Web Workers.

Cas 4 : écouteurs de scroll non passifs

Celui-là est sournois. Un écouteur de scroll qui n'est pas marqué passif force le navigateur à attendre et à vérifier si tu vas appeler preventDefault. À chaque pixel de scroll. Ça fige le compositeur net, et sur un téléphone le premier tap juste après un scroll explose soudain sans prévenir. Il m'a fallu un temps fou pour comprendre pourquoi.

Before, INP 380 ms

window.addEventListener('scroll', () => {
  updateProgressBar();
});

After, INP 110 ms

window.addEventListener('scroll', () => {
  requestAnimationFrame(updateProgressBar);
}, { passive: true });

CLS : code avant/après et optimisations

Le CLS mesure ce que tu détestes en tant qu'utilisateur. Tu vas pour appuyer sur un bouton, et toute la page sursaute. Il comptabilise chaque décalage inattendu pendant que la page se stabilise : une bannière qui surgit en retard, ou le swap de police qui reflow discrètement un paragraphe sous ton pouce. Une image sans espace réservé fait pareil. Tout ça s'additionne, et rien de tout ça n'est la faute de l'utilisateur, pourtant c'est lui qui jure contre son écran.

Cas 5 : image sans dimensions

Before, CLS 0.28

<img src="/article/figure.jpg"
     alt="Diagram">
<!-- no dimensions, the browser
     cannot reserve space -->

After, CLS 0.02

<img src="/article/figure.jpg"
     width="800" height="450"
     style="aspect-ratio:800/450;
            max-width:100%;height:auto"
     alt="Diagram">

Cas 6 : bandeau cookies qui pousse le contenu vers le bas

Le bandeau cookies débarque 800 ms après le LCP, s'insère en haut du body, et repousse tout ce qui se trouve dessous vers le bas de la page. J'ai vu un bandeau faire grimper le CLS au-delà de 0,30 à lui tout seul et emporter la métrique entière avec lui.

Before, CLS 0.32

// Inject banner into body at runtime
document.body.prepend(banner);

After, CLS 0.03

/* Banner at fixed position at bottom */
.cookie-banner{
  position:fixed; bottom:0; left:0; right:0;
  z-index:9999;
}
/* OR reserve space in the HTML:
   <div id="cookie-slot"
        style="height:0;overflow:hidden"></div> */

Optimisations spécifiques à WordPress

La plupart de mes sites clients tournent sous WordPress, et il arrive avec une poignée de pièges qui mordent de la même façon à chaque fois. La liste ci-dessous suit à peu près l'ordre dans lequel je les traite. Sur un site typique, ça tire environ 30 points sur le score Lighthouse mobile et fait basculer les trois vitals au vert. À peu près. Ça varie selon le thème, évidemment.

  • Plugin de cache de page : WP Rocket, LiteSpeed Cache ou W3 Total Cache. Sers le HTML directement depuis le cache au lieu de le reconstruire à chaque requête, et le TTFB s'effondre. De 800 ms à 80 ms, d'après mon expérience. C'est vers celui-là que tu te tournes en premier. Il vaut généralement à lui seul environ 700 ms de LCP.
  • Désactiver les scripts globaux inutilisés : Contact Form 7, WooCommerce, Elementor. Ils chargent allègrement leur JS sur des pages qui n'en utilisent pas une ligne. Asset CleanUp ou Perfmatters te permet de les couper page par page, et chaque script que tu tues vaut 100 à 250 ms d'INP.
  • Lazy-load natif sauf le hero : branche add_filter('wp_get_attachment_image_attributes', ...) pour forcer fetchpriority="high" sur la première image de contenu, et laisse le lazy sur tout le reste. C'est juste la version code du correctif hero vu plus haut.
  • Compresser et convertir les images en AVIF : ShortPixel, Imagify ou Smush en mode « priorité AVIF ». C'est là que j'ai vu 1 à 2 s tomber de l'image LCP, et au passage ta facture de bande passante baisse de 30 à 50 pour cent.
  • Précharger la police web critique : glisse un <link rel="preload" as="font"> via le filtre wp_head, ou confie le boulot au plugin Pre* Party Resource Hints si tu préfères ne pas toucher au PHP du tout.
  • Désactiver les emojis et embeds inutilisés : remove_action('wp_head', 'print_emoji_detection_script', 7) et remove_action('wp_head', 'wp_oembed_add_discovery_links'). Pris isolément c'est minuscule, d'accord. Mais ça s'empile. Disons 50 à 100 ms que tu n'avais aucune raison de laisser traîner sur la table.

Optimisations spécifiques à Cloudflare

Déjà derrière Cloudflare, en formule gratuite ou Pro ? Il y a tout un tas d'interrupteurs dans le panneau Speed qui rapportent à l'instant où tu les actives, sans une ligne de code et sans rien déployer.

  • Early Hints (gratuit) : Cloudflare envoie un 103 Early Hints qui transporte tes preload et preconnect avant même que ton origine ait dit un mot, de sorte que le navigateur commence à charger tôt. J'en tire 200 à 400 ms de LCP sur les chargements à froid.
  • HTTP/3 et 0-RTT (gratuit) : active les deux sous Network. Ça ne bougera pas grand-chose sur la fibre. Sur une connexion mobile instable, en revanche, c'est un solide 100 à 200 ms de LCP.
  • Auto Minify et Brotli (gratuit) : compresse ton HTML/CSS/JS à la sortie, 15 à 25 pour cent de moins à télécharger. Gain gratuit. Laisse-le activé et oublie-le.
  • Cache Reserve (Pro) : parque tes assets statiques dans un cache persistant longue durée pour que Cloudflare arrête de téléphoner à ton origine pour revalider à chaque fois.
  • Désactiver Rocket Loader : ignore le nom optimiste. Il sérialise le chargement de ton JS et empire l'INP sur tout ce qui est un tant soit peu moderne. Le couper m'a rapporté environ 150 ms d'INP plus de fois que je ne peux les compter.
  • Image Resizing / Polish (Pro) : conversion AVIF/WebP plus redimensionnement par appareil directement à l'edge. Sur mobile, c'est encore 1 à 1,5 s de moins sur l'image LCP, et tu ne touches jamais à ta médiathèque.

Pas même certain que Cloudflare soit dans le chemin ? Notre CDN Detector te dit en quelques secondes s'il est actif et quel cache a réellement servi la requête.

Lire correctement une capture Lighthouse

Un panneau Lighthouse t'affiche le LCP, l'INP/TBT et le CLS côte à côte, chacun avec un badge « Good » une fois qu'il passe. Des chiffres faciles à mal lire, cela dit, alors voici comment je les lis.

Je ne fais jamais confiance à une capture tant que je n'ai pas vérifié deux ou trois choses. 1) Lighthouse ne t'affichera pas l'INP du tout. Il affiche le TBT en espérant discrètement que tu le prendras comme un substitut. Tu veux le vrai INP ? Instrumente avec web-vitals, ou lis-le directement dans le « Field Data » de PageSpeed Insights. 2) Ce score sur 100 est pondéré, ce n'est pas une moyenne. Le LCP pèse 25 pour cent, le TBT 30, le CLS 25, le FCP 10, le Speed Index 10. Donc tu peux afficher un beau 90 et quelques et quand même être coulé si un seul vital reste bloqué en orange. 3) Lighthouse mobile te bride volontairement, CPU 4x plus lent et réseau Slow 4G. Les chiffres ont l'air brutaux, et c'est fait exprès. C'est tout l'intérêt, parce que c'est bien plus proche du téléphone dans la main de ton visiteur que ta machine de dev ne le sera jamais.

Sources et lectures complémentaires

Questions fréquentes

Combien de temps avant qu'une optimisation apparaisse dans la Search Console ?

Plus lent que tu ne le voudrais. CrUX tourne sur une fenetre glissante de 28 jours, donc sur une page tres frequentee tu attraperas le premier fremissement dans la Search Console apres environ 7 jours, mais le chiffre ne se stabilisera vraiment qu'au 28e jour. Cette attente est exasperante quand tout ce que tu veux savoir, c'est si le correctif a bel et bien pris. Alors ne reste pas plante la a rafraichir. Greffe la bibliotheque web-vitals sur tes pages, envoie les chiffres vers ta propre analytics, et tu auras ta reponse en moins de 24 heures.

Mon score Lighthouse est de 95 mais la Search Console affiche orange. Je fais quoi ?

Bienvenue dans l'ecart labo-vs-terrain. Je tombe dessus sans arret, honnetement c'est peut-etre la confusion la plus frequente qu'on me soumet. Lighthouse chronometre ta machine rapide. La Search Console rapporte tes vrais visiteurs, qui sont en majorite sur des telephones et des reseaux moyens. Ouvre le rapport CrUX dans PageSpeed Insights, trouve la metrique terrain passee au rouge, corrige celle-la. Et quoi que tu fasses, ne brule pas tout un apres-midi a tirer Lighthouse de 95 a 100. Ces cinq derniers points, aucun utilisateur ne les sentira jamais.

Un plugin de cache premium vaut-il le coup de payer en 2026 ?

Ca depend entierement de chez qui tu es heberge. Sur de l'hebergement mutualise type OVH ou Hostinger ? Oui, sans hesiter. WP Rocket (ou LiteSpeed Cache, qui est gratuit si par hasard tu es sur un serveur LiteSpeed) c'est la frontiere entre un site mou et un site vif, et c'est la vitesse la moins chere que je connaisse. Mais sur un vrai hebergement manage, ton Kinsta, ton WP Engine ou ton O2switch, leur propre cache cote serveur fait deja l'essentiel du gros oeuvre, donc un plugin gratuit comme Cache Enabler suffit amplement. Aucun interet a payer deux fois le meme cache.

Mes images sont deja compressees, pourquoi mon LCP est-il toujours mauvais ?

Des fichiers plus petits ne servent a rien si le navigateur atteint l'image en retard, et c'est en general exactement ce qui se passe. Quelques coupables que je verifierais, dans l'ordre. D'abord, l'image LCP est lazy-loadee ; regarde son attribut loading en premier, c'est de loin le fautif le plus courant. Ensuite, du JavaScript injecte le img apres le DOMContentLoaded, donc le navigateur ne tombe dessus qu'une fois la fete finie ; rends-le plutot dans le HTML serveur. Enfin, ton origine est tout simplement lente, TTFB au-dela de 800 ms, et aucune astuce d'image sur terre ne repare un serveur lent. Active un cache de page ou change d'hebergement.

Comment prioriser si je n'ai qu'une journee pour optimiser ?

Voici l'ordre exact dans lequel je travaille quand le temps me presse. D'abord, active un cache de page, le plus gros gain de LCP pour le moindre effort. Ensuite, arrache loading=lazy de l'image hero. Puis mets width et height sur chaque image pour que rien ne saute. Precharge ta police web principale. Coupe enfin les plugins lourds que personne n'utilise vraiment. Ces cinq-la a eux seuls t'emmenent quasiment au bout, autour de 80 pour cent du gain, en general avant le dejeuner.