Comment trouver et corriger les problèmes de CLS (Cumulative Layout Shift)
Quelles pages échouent, quel élément bouge, pourquoi vous ne le voyez pas vous-même et comment le reproduire dans Chrome.
- Bon ≤ 0,1
- À améliorer ≤ 0,25
- Mauvais > 0,25
Partager
Trouver et corriger le CLS en bref
Le Cumulative Layout Shift (CLS) est le Core Web Vital de la stabilité visuelle, bon à 0,1 ou moins au 75e percentile. Pour identifier la cause, repérez l'élément qui a bougé dans les données d'utilisateurs réels et regardez ce qui se trouve au-dessus. Reproduisez ensuite le shift dans Chrome avec le cache désactivé : une première visite montre les shifts qu'une visite avec cache masque.
Par où commencer face à un problème de CLS ?
Partez de vos vrais visiteurs pour remonter jusqu'au code : quelles pages échouent sur quel appareil, quel élément a bougé et quand, le shift dans Chrome, puis sa cause. Corrigez le plus grand shift en premier, car c'est lui qui fait le plus baisser le score.
Le CLS se mesure à deux endroits : dans les field data issues des vrais visiteurs, sur lesquelles Google se base pour son classement et que Search Console et le real-user monitoring (RUM) rapportent, et dans Chrome sur votre propre ordinateur, où DevTools et l'API Layout Instability montrent pourquoi une page bouge. Le guide du Cumulative Layout Shift explique comment chaque shift est noté et pourquoi seule la pire rafale de shifts compte.
| Étape | Où regarder | Ce que cela indique |
|---|---|---|
| 1. Pages | Search Console | Quels groupes d'URL échouent, sur quel appareil, depuis quand |
| 2. Élément | Real-user monitoring (RUM) | Quel élément a bougé, sur quelles pages, pendant ou après le chargement |
| 3. Reproduire | Chrome DevTools, cache désactivé | Ce qu'un nouveau visiteur voit bouger, et pourquoi |
| 4. Logger | API Layout Instability | Chaque shift avec ses éléments |
| 5. Corriger | Le tableau des causes ci-dessous | Que modifier, et où |
| 6. Vérifier | Le même enregistrement, puis le RUM | Si le shift a disparu |
Quelles pages échouent au CLS dans Search Console ?
Le rapport Core Web Vitals de Search Console affiche « Problème CLS : supérieur à 0,1 (mobile) » quand un groupe d'URL similaires a un CLS supérieur à 0,1 au 75e percentile des visites sur mobile (à améliorer), et « Problème CLS : supérieur à 0,25 (mobile) » quand il dépasse 0,25 (médiocre) ; « (desktop) » indique la même chose pour les visites sur ordinateur. Chaque problème liste ses groupes d'URL avec une URL d'exemple par groupe, ce qui vous indique quel template échoue. L'élément qui bouge provient des données d'utilisateurs réels ou d'un enregistrement de cette URL d'exemple dans Chrome.
D'après le State of Web Vitals, 88,9 % des sites ont un bon CLS sur mobile contre 78,0 % sur desktop : ouvrez donc aussi l'onglet desktop.
Regardez ensuite la tendance sur le graphique du problème. Un saut soudain signifie qu'une release a ajouté un élément, comme une bannière ou un emplacement publicitaire : notez la date et cherchez ce qui a été mis en ligne une à trois semaines plus tôt, car le rapport utilise les 28 derniers jours de visites.

Search Console, Problème CLS : supérieur à 0,25 (mobile) sur acme-corp.com : commencez par l'URL d'exemple du plus grand groupe.
Quel élément a bougé, sur quelles pages et quand ?
Le real-user monitoring (RUM) enregistre quel élément a bougé lorsque la page a shifté chez vos visiteurs : dans CoreDash, regroupez le CLS sur mobile par Attribution Element (CLS). Cet élément a été poussé : la cause est donc généralement ce qui se trouve directement au-dessus : une barre, un emplacement publicitaire, une image ou une ligne de texte dans une police web.
J'ai créé CoreDash pour montrer quel élément a bougé, sur quelles pages et pour quels visiteurs. Segmentez ensuite les données un segment à la fois :
- Pages : Top level Pathname, ou Page label si vous donnez un libellé à chaque template, indique si un seul template bouge ou si toutes les pages sont touchées.
- Device : analysez mobile et desktop séparément, car un layout qui change à un breakpoint peut bouger sur l'un et rester stable sur l'autre.
- Load State (CLS) : quand le plus grand shift s'est produit, pendant le chargement (loading, dom-interactive, dom-content-loaded) ou après l'événement load (complete). Un shift pendant le chargement correspond à la page qui construit son layout ; un shift survenu après provient d'un contenu arrivé en retard ou d'une action du visiteur.
- Last Interaction (CLS) : ce que le visiteur a fait juste avant le plus grand shift : rien, un tap ou un clic, une touche au clavier ou un scroll. Chrome comptabilise chaque shift après un scroll, et chaque shift survenu plus de 500 millisecondes après un tap ou une touche au clavier.
- Repeat Visitor : nouveaux visiteurs contre visiteurs récurrents. Un shift que seuls les nouveaux visiteurs rencontrent pointe vers un fichier que les visiteurs récurrents ont déjà dans le cache du navigateur.

CoreDash, CLS sur mobile par Load State (CLS) sur acme-pagespeed.com : trouvez la ligne avec le p75 le plus élevé. Quand il s'agit de la ligne complete, comme ici, regroupez ensuite ces chargements de page par Last Interaction (CLS).
Un site disposant de son propre RUM récupère l'élément et le load state du plus grand shift via le build d'attribution de la bibliothèque web-vitals de Google : largestShiftTarget et loadState.
Pourquoi ne voyez-vous pas le layout shift sur votre propre ordinateur ?
Une police web ou une image sans taille exploitable ne décale la page que tant que le fichier n'est pas dans le cache du navigateur : votre propre visite récurrente masque donc le problème. Une barre ou une annonce insérée par un script décale la page à chaque visite, et un shift après un scroll ou un tap n'apparaît jamais dans un test Lighthouse, qui charge la page une seule fois sans toucher à rien.
Sur une page de test de recette présentant quatre layout shifts, une visite récurrente avec les fichiers en cache en conservait encore deux : la barre de newsletter (0,058) et l'annonce (0,054). Les shifts causés par la police web du titre et la photo sans dimensions avaient disparu. Activez Disable cache dans Chrome DevTools avant de juger une page.
Sur les sites mesurés avec CoreDash, environ 7 chargements de page sur mobile sur 10 affichant un CLS médiocre ont subi leur plus grand layout shift après un scroll ou un tap du visiteur, sur les 28 jours précédant le 12 novembre 2026. Quand Lighthouse est au vert et Search Console au rouge, regardez Last Interaction (CLS) en premier.
Un plugin qui retarde le JavaScript jusqu'au premier scroll ou tap, comme WP Rocket avec Delay JavaScript execution activé, élimine le shift dans Lighthouse, mais vos visiteurs le subissent toujours : ce que le script insère arrive généralement plus de 500 millisecondes après leur scroll ou leur tap, et Chrome comptabilise donc le shift.
Comment reproduire le layout shift dans Chrome ?
Chargez la page comme le fait un nouveau visiteur sur mobile : DevTools ouverts au format mobile, Disable cache activé, Slow 4G, puis enregistrez le rechargement et un scroll dans le panneau Performance. Chaque layout shift est un losange violet dans la piste Layout shifts, et son survol met en surbrillance l'élément qui a bougé.
- Un premier aperçu : le Core Web Vitals Visualizer, une extension Chrome gratuite, superpose un calque sur tout ce qui a bougé pendant le chargement de la page.

Le Core Web Vitals Visualizer sur une page de test, avec la zone qui a bougé en rouge.
- Chargez la page comme un nouveau visiteur : dans le panneau Network, cochez Disable cache (qui fonctionne tant que les DevTools sont ouverts) et choisissez Slow 4G. Quand vos field data indiquent le mobile, activez la barre d'outils des appareils (Ctrl+Shift+M, Cmd+Shift+M sur Mac) avec un format mobile. Sur une connexion lente, la page effectue son paint avant que chaque fichier ne soit arrivé : les shifts causés par des fichiers tardifs apparaissent donc (réglages du panneau Network).
- Enregistrez un rechargement et un scroll : dans le panneau Performance, cochez Screenshots, cliquez sur Record, rechargez la page, scrollez vers le bas comme le ferait un visiteur, puis cliquez sur Stop (enregistrer une trace). Le bouton Record and reload s'arrête tout seul quelques secondes après le chargement, avant que vous n'ayez pu scroller. Cliquez sur un losange : le Summary affiche son timing, son score, les éléments qui ont bougé et les causes probables identifiées par Chrome. Ce qui ressemble à un seul layout shift correspond souvent à plusieurs shifts successifs, un cluster de losanges très rapprochés : cliquez sur chacun d'eux, car chacun peut avoir sa propre cause.

Enregistrement d'un scroll sur une page de boutique de test : chaque losange dans la piste Layout shifts est un shift survenu après le chargement.
- Vérifiez l'élément cité par Chrome ou Lighthouse : les deux déduisent la cause du timing : une image dimensionnée qui a seulement été poussée peut ainsi se retrouver listée comme « Unsized image element ». Dans le panneau Elements, assurez-vous que l'image manque réellement de width et de height avant de la modifier, ou bloquez la requête suspecte et enregistrez à nouveau : si un losange disparaît, il dépendait de cette requête (comment vérifier).
Pour un aperçu rapide sans enregistrement, l'option Layout Shift Regions dans le tiroir Rendering fait clignoter chaque zone qui bouge, et la vue des métriques en direct du panneau Performance affiche le CLS et vos interactions au fil de vos taps et de vos scrolls.
Un shift visible sur certains chargements et pas sur d'autres est souvent dû à un transition: all dans le thème, qui anime width, height ou margin pendant la construction de la page. Pour le tester, ajoutez cette ligne dans le head du HTML de la page avec Local Overrides (panneau Sources, Overrides), ce qui la conserve à chaque rechargement, puis relancez un enregistrement :
<style>* { transition-property: none !important; }</style> Si les losanges ont disparu, une transition en était la cause ; l'article sur les layout shifts causés par les transitions CSS montre comment identifier laquelle. Un style collé dans la console est perdu au rechargement : la console ne permet donc pas d'effectuer ce test.
Comment logger chaque layout shift avec l'API Layout Instability ?
L'API Layout Instability remonte chaque layout shift avec son score, son timing et jusqu'à cinq éléments qui ont bougé (sources), chacun avec sa position avant et après (previousRect et currentRect). Les shifts survenus dans les 500 millisecondes suivant un tap, un clic ou une touche portent hadRecentInput, et le snippet les ignore, comme le fait le CLS. Collez ceci dans la console une fois la page chargée ; buffered: true liste également les shifts survenus avant le collage :
new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
if (entry.hadRecentInput) continue;
console.log(Math.round(entry.startTime) + ' ms', entry.value.toFixed(4));
for (const source of entry.sources || []) {
const moved = Math.round(source.currentRect.y - source.previousRect.y);
console.log(' moved ' + moved + ' px', source.node);
}
}
}).observe({ type: 'layout-shift', buffered: true }); Les nœuds correspondent aux éléments qui ont bougé : regardez donc ce qui se trouve au-dessus d'eux. L'API fonctionne dans les navigateurs Chromium comme Chrome et Edge.
Quelle est la cause du shift et où trouver le fix ?
Chaque constat pointe vers une cause probable, et chaque fix consiste soit à réserver l'espace avant l'arrivée du contenu, soit à déplacer le contenu sans altérer le layout. Commencez par le plus grand shift.
| Ce que vous observez | Cause probable | Le fix |
|---|---|---|
| Le texte bouge au chargement de la police, premières visites | Le swap d'une police web | Polices web |
| Le contenu sous une image bouge, premières visites | Une image sans dimensions, ou le width: auto d'un thème | Dimensions des images |
| La page descend de la hauteur d'une barre, à chaque visite | Une barre ou une bannière insérée au-dessus du header | Barres et bannières |
| Le contenu sous une annonce bouge tardivement, à chaque visite | Une annonce ou un embed qui remplit son slot | Annonces et embeds |
| Le header ou le menu change de taille après le premier paint | Du CSS chargé tardivement | CSS tardif |
| Shifts sur certains chargements et pas sur d'autres | Une transition dans le thème | Animations |
| Shifts pendant le scroll | Un effet de scroll, ou une image en lazy loading sans dimensions | Effets de scroll, Dimensions des images |
Une animation de chargement ne fait que reporter le shift au moment où le vrai contenu la remplace, sauf si cette animation possède déjà la taille finale de ce contenu. Le guide Images et médias traite des vidéos, des iframes et des carrousels.
La plupart de ces fixes commencent par un réglage :
- WordPress : passez le plugin de barre ou de consentement en affichage barre inférieure, bandeau flottant ou popup ; dans WP Rocket, activez Add missing image dimensions sous Media ; excluez la feuille de style du thème du CSS différé ou asynchrone ; attribuez une hauteur fixe au slot du plugin publicitaire. Retrouvez le détail par plugin dans le guide WordPress.
- Shopify : donnez une hauteur au conteneur des app blocks (comme les étoiles d'avis ou une barre d'annonces), et définissez un width et un height sur chaque
<img>générée directement par le thème (guide Shopify). - Pour votre développeur : transmettez l'élément issu des données d'utilisateurs réels, le groupe d'URL de Search Console et l'enregistrement montrant le shift. Un shift de police web ne dispose d'aucun réglage sur ces plateformes : demandez une police de fallback dimensionnée pour correspondre à la police web.
Comment vérifier que le fix du CLS a fonctionné ?
Enregistrez à nouveau la même page avec le cache désactivé et le même scroll, puis vérifiez que le losange violet du shift a disparu de la piste Layout shifts. Dans les données d'utilisateurs réels, l'élément disparaît de la liste Attribution Element (CLS) quelques jours après le fix.
Si l'élément reste dans la liste avec un score plus bas, le shift a diminué mais persiste : visez un CLS de 0. Dans Search Console, cliquez sur Valider la correction sur le problème ; le rapport met jusqu'à 28 jours pour passer au vert, car il affiche les 28 derniers jours de visites.
Il arrive que l'élément présent dans vos données d'utilisateurs réels ne bouge jamais lors de l'enregistrement de la page : le shift provient d'une annonce affichée uniquement à certains visiteurs, ou d'un élément situé bien plus bas sur la page après un scroll. Lors d'une Core Web Vitals power hour, nous mettons vos données d'utilisateurs réels en regard d'un enregistrement de ce template pour identifier ce qui déclenche le shift.

Besoin d'un site plus rapide ?
Je suis Arjen et je répare des sites lents depuis 17 ans. Si vous rencontrez des problèmes que vous ne pouvez pas résoudre vous-même, envoyez-moi votre URL et parlons-en.
Envoyez-moi votre URL
Pourquoi notre fix ne fonctionne pas ?
Parfois le CDN sert encore l'ancien HTML, ou le fix a été appliqué sur le template desktop alors que le mobile en utilise un autre. Envoyez-moi votre URL et le problème, et je vous réponds avec quelques créneaux. J'analyse d'abord vos field data, puis nous passons une heure sur votre site, et sous 24 heures vous avez mes notes par écrit. 350 € HT.
Envoyez-moi votre URLPas de développeur pour réaliser le fix ? Je fais le travail moi-même, sur une copie de votre site.