Le CLS (Cumulative Layout Shift) quantifie à quel point la mise en page de votre site « saute » pendant qu'elle se charge. Vous connaissez l'expérience : vous allez cliquer sur un bouton, une bannière de pub se charge en haut, tout descend, vous cliquez sur autre chose. C'est ça, un mauvais CLS — et Google le pénalise depuis 2021 dans les Core Web Vitals. Les seuils : ≤ 0,1 = bon, 0,1-0,25 = à améliorer, > 0,25 = mauvais (au 75e percentile).
Le calcul est simple à comprendre : pour chaque élément qui bouge entre deux frames, on multiplie la fraction de viewport impactée (impact fraction) par la distance de déplacement (distance fraction). On somme tout ça pendant la durée de vie de la page. Les coupables habituels : (1) images sans dimensions explicites (`width`/`height`), (2) fonts web qui provoquent un FOUT (Flash of Unstyled Text) en se chargeant, (3) bannières de pub ou cookies insérées dynamiquement en haut, (4) embeds (Twitter, YouTube) qui s'auto-redimensionnent, (5) animations CSS sur des propriétés non-composites.
Les fixes sont généralement rapides — on les traite en quelques heures pendant un audit gratuit. Côté code : toujours déclarer `width` et `height` sur les images (ou utiliser le composant Image de Next.js qui le fait), utiliser `font-display: optional` ou des fallbacks bien configurés, réserver l'espace des publicités/embeds avec un placeholder de bonne taille, animer uniquement `transform` et `opacity`. Le CLS est le plus facile des trois Core Web Vitals à fixer — quand il est rouge, c'est qu'il manque juste de la rigueur côté front. On le corrige sur tous nos sites sur-mesure.
Les 4 causes principales d'un mauvais CLS
- Images sans dimensions : toujours `width`/`height` (ou `aspect-ratio`) — c'est 80 % des cas en pratique.
- Fonts web mal configurées : `font-display: optional` ou fallback `size-adjust` pour éviter le saut au swap.
- Pubs/cookies dynamiques en haut de page : réserver un container fixe ou les afficher en bas/sticky.
- Animations CSS non-composites : animer `transform`/`opacity` plutôt que `top`/`left`/`width`/`height`.
