Nous l’avons tous vécu : on lit un article et le texte glisse vers le bas parce qu’une publicité est apparue au-dessus ; on s’apprête à toucher un bouton et, un instant avant, un autre élément prend sa place. C’est la sensation d’une page « instable », et parmi les Core Web Vitals, elle a sa propre métrique : le CLS, Cumulative Layout Shift. Des trois métriques, c’est la moins intuitive à calculer, mais souvent la plus facile à corriger, et son impact sur l’expérience et sur les conversions est très concret.
Ce que mesure le CLS
Le CLS mesure la stabilité visuelle d’une page, c’est-à-dire de combien les éléments visibles changent de position de façon inattendue pendant que l’utilisateur s’en sert. Il ne compte pas le temps, comme le LCP et l’INP, mais le mouvement : c’est d’ailleurs la seule des trois Core Web Vitals qui ne s’exprime pas en secondes ou en millisecondes, mais par un score sans unité de mesure.
Les seuils, évalués comme pour les autres métriques au 75e percentile des visites réelles, sont les suivants : jusqu’à 0,1, le résultat est bon ; entre 0,1 et 0,25, il est à améliorer ; au-delà de 0,25, il est médiocre. Un seul grand décalage peut suffire à franchir le seuil.
Le mot « inattendu » compte. Si l’utilisateur touche un bouton qui ouvre un panneau et que le contenu se déplace pour lui faire de la place, le décalage est une réponse attendue et n’est pas compté : les décalages qui surviennent dans les 500 millisecondes suivant une interaction comme un clic, un toucher ou une pression de touche sont exclus. Le défilement de la page, en revanche, ne compte pas comme une interaction de ce type, et les animations réalisées avec la propriété CSS transform ne produisent pas de décalages de mise en page.
Comment le score est calculé
Chaque fois qu’un élément visible change de position d’une image à la suivante, le navigateur calcule le score de ce décalage en multipliant deux valeurs. La fraction d’impact est la portion du viewport occupée par l’élément avant et après le décalage, prises ensemble. La fraction de distance est le plus grand déplacement, divisé par la plus grande dimension du viewport.
Dans l’exemple, un bloc de la moitié de la hauteur de l’écran descend d’un quart de la hauteur de l’écran : ensemble, les positions de départ et d’arrivée couvrent 75 % du viewport, et le déplacement est de 25 %. Le score est 0,75 × 0,25 = 0,19, déjà au-dessus du seuil de « bon ». Deux conséquences pratiques : les grands éléments pèsent bien plus que les petits, et même un décalage de quelques pixels dans un bloc qui remplit la majeure partie de l’écran peut coûter cher. C’est pourquoi, sur smartphone, où une image ou une bannière occupe presque tout le viewport, le CLS tend à être pire que sur desktop.
Les fenêtres de session
Le « cumulatif » du nom ne signifie pas que tous les décalages d’une visite s’additionnent. Depuis 2021, le CLS regroupe les décalages en fenêtres de session : une fenêtre se ferme quand plus d’une seconde s’écoule sans décalage, et elle ne peut pas durer plus de cinq secondes. Le CLS de la visite est la somme des décalages de la pire fenêtre.
Cette garantie évite de pénaliser les pages qui restent ouvertes longtemps, comme les applications ou les articles à défilement infini, où quelques petits décalages isolés s’additionneraient de façon irréaliste. Mais elle signifie aussi qu’une rafale de décalages concentrée sur quelques secondes, typique du chargement initial, pèse assez pour compromettre le résultat.
Pourquoi le CLS est une affaire de business
Un décalage de mise en page n’est pas seulement agaçant. Il provoque des clics erronés : sur une publicité au lieu du lien voulu, sur « annuler » au lieu de « confirmer », sur un autre produit que celui qu’on voulait. Il fait perdre sa place dans le texte, oblige à la retrouver, et donne l’idée d’un site peu soigné au moment même où l’utilisateur décide s’il peut lui faire confiance. Sur les sites e-commerce et d’information, où les publicités, les bannières promotionnelles et les widgets se chargent souvent après le contenu, le CLS est l’un des premiers indicateurs à contrôler. Et, comme composante des Core Web Vitals, il contribue à l’évaluation de l’expérience de page par Google.
Les causes les plus courantes
- Images et vidéos sans dimensions. Si le navigateur ne connaît pas à l’avance la largeur et la hauteur d’une image, il réserve zéro pixel et décale tout ce qui suit à l’arrivée du fichier.
- Publicités, embeds et iframes. Les emplacements publicitaires, les vidéos intégrées, les cartes et les widgets sociaux ont souvent des dimensions connues seulement après le chargement, et parfois variables selon la publicité diffusée.
- Contenu inséré après le rendu. Bandeaux d’information, bannières promotionnelles, bandeaux de cookies en haut de page, messages personnalisés, badges d’avis : tout élément ajouté au-dessus d’un contenu déjà visible le pousse vers le bas.
- Polices web. Quand la police du site remplace la police de secours, un texte aux métriques différentes modifie la hauteur et la largeur des lignes, ce qui décale les blocs suivants.
- Styles qui arrivent tard. Un CSS chargé de façon asynchrone ou après une interaction, comme cela se produit avec certaines techniques de suppression du CSS inutilisé ou avec des composants initialisés par du JavaScript différé, change l’aspect de la page après le premier rendu.
- Animations sur des propriétés de mise en page. Animer
top,heightoumargindéplace les éléments voisins à chaque image.
Comment le réduire
Il n’y a qu’une règle générale : chaque élément doit avoir son espace réservé dès le premier rendu. Pour les images, il suffit d’indiquer les dimensions dans le balisage, en laissant le CSS les adapter tout en conservant les proportions :
<img src="produit.webp" width="1200" height="800" alt="…">
img {
max-width: 100%;
height: auto; /* le navigateur utilise width/height pour calculer les proportions */
}
/* espace réservé pour une bannière publicitaire de hauteur connue */
.slot-adv {
min-height: 250px;
}
- Réserver l’espace des publicités et des embeds avec une hauteur minimale ou avec
aspect-ratio, même quand la publicité risque de ne pas arriver : un espace vide vaut mieux qu’un décalage. - Ne pas insérer de contenu au-dessus de ce qui est déjà visible. Les bandeaux et les avis doivent être prévus dans la mise en page dès le départ, superposés en bas ou affichés en réponse à une interaction.
- Aligner les polices de secours. Précharger la police principale et utiliser des descripteurs comme
size-adjustet les surcharges de métriques dans la police de secours réduit le décalage au moment du remplacement. - Animer avec transform et opacity. Ces propriétés ne modifient pas la mise en page et ne produisent pas de décalages.
- Rendre les pages éligibles au back/forward cache. Quand l’utilisateur revient en arrière, une page restaurée depuis le cache du navigateur s’affiche instantanément et sans décalages.
Comment le mesurer, et pourquoi le laboratoire ne suffit pas
Le CLS se mesure en laboratoire comme sur le terrain, mais avec une différence importante. Lighthouse, et donc la section laboratoire de PageSpeed Insights, n’observe que le chargement initial, sans défilement et sans interaction. Tout ce qui se passe ensuite, comme une image sans dimensions qui entre dans l’écran pendant le défilement, une publicité qui se charge à mi-page ou une bannière qui apparaît au bout de dix secondes, n’existe pas en laboratoire. Les données d’utilisateurs réels, elles, enregistrent toute la visite. C’est pourquoi il n’est pas rare de trouver un CLS parfait en laboratoire et insuffisant sur le terrain : c’est l’une des raisons pour lesquelles il faut à la fois CrUX et les données de laboratoire.
Pour trouver les décalages, Chrome DevTools met en évidence les zones qui bougent pendant le chargement et, dans le panneau Performance, une piste dédiée aux décalages de mise en page avec les éléments concernés. Sur le terrain, la bibliothèque open source web-vitals, dans sa version avec attribution, identifie l’élément responsable du plus grand décalage :
import { onCLS } from 'web-vitals/attribution';
onCLS( ( { value, attribution } ) => {
console.log( 'CLS', value.toFixed( 3 ), {
element: attribution.largestShiftTarget,
time: Math.round( attribution.largestShiftTime ),
loadState: attribution.loadState,
} );
} );
Savoir quel élément se décale, et si cela arrive pendant le chargement ou plus tard, suffit souvent à trouver la cause. Et, comme pour les autres métriques, les améliorations apparaissent dans les données CrUX progressivement, sur la fenêtre de 28 jours.
En résumé
Le CLS mesure de combien la page bouge sous les yeux et sous les doigts de l’utilisateur. Chaque décalage inattendu vaut fraction d’impact multipliée par fraction de distance, les décalages sont regroupés en fenêtres de session et la pire fenêtre compte ; le seuil de « bon » est de 0,1 au 75e percentile. Les causes sont presque toujours les mêmes : images et publicités sans espace réservé, contenu inséré au-dessus de ce qui est visible, polices et styles qui arrivent tard.
La bonne nouvelle, c’est que, contrairement au LCP et à l’INP, le CLS demande rarement un travail sur l’infrastructure : dans la plupart des cas, il suffit de concevoir la mise en page pour que chaque élément ait sa place dès le départ. C’est l’un des investissements au meilleur rapport entre effort et résultat, pour les utilisateurs comme pour l’entreprise.