Des décalages de mise en page inattendus peuvent perturber l'expérience utilisateur à bien des égards : ils peuvent perdre leur place pendant la lecture si le texte se déplace soudainement, ou les amener à cliquer sur le mauvais lien ou le mauvais bouton. Dans certains cas, cela peut causer de graves dommages.
Un déplacement inattendu du contenu de la page se produit généralement lorsque les ressources se chargent de manière asynchrone ou lorsque des éléments DOM sont ajoutés de façon dynamique à la page avant le contenu existant. Ces décalages peuvent être dus à des images ou des vidéos dont les dimensions sont inconnues, à des polices dont l'affichage est supérieur ou inférieur à celui de la création de remplacement initiale, ou à des annonces ou widgets tiers qui se redimensionnent de manière dynamique.
Les différences entre le fonctionnement d'un site pendant le développement et celui de ses utilisateurs aggravent le problème. Exemple :
- Le contenu personnalisé ou tiers se comporte souvent différemment lors du développement et en production.
- Les images de test se trouvent souvent déjà dans le cache du navigateur du développeur, mais leur chargement est plus long pour l'utilisateur final.
- Les appels d'API exécutés localement sont souvent si rapides que des retards de développement inaperçus peuvent s'avérer importants en production.
La métrique CLS (Cumulative Layout Shift) vous aide à résoudre ce problème en mesurant la fréquence à laquelle il se produit pour des utilisateurs réels.
Qu'est-ce que le CLS ?
Le CLS est une mesure des scores de décalage de mise en page les plus importants pour chaque décalage de mise en page inattendu qui se produit pendant l'ensemble du cycle de vie d'une page.
Un décalage de mise en page se produit chaque fois qu'un élément visible passe d'une image affichée à l'autre. (Les détails du calcul des scores de décalage de mise en page individuels sont abordés plus loin dans ce guide.)
Une rafale de décalages de mise en page, appelés fenêtres de session, se produit lorsqu'un ou plusieurs changements de mise en page individuels se produisent rapidement successivement, avec moins d'une seconde entre chaque changement et un maximum de cinq secondes pour la durée totale de la fenêtre.
La plus grande rafale est la fenêtre de session avec le score cumulé maximal de tous les décalages de mise en page dans cette fenêtre.
Qu'est-ce qu'un bon score CLS ?
Pour offrir une expérience utilisateur de qualité, les sites doivent s'efforcer d'obtenir un score CLS inférieur ou égal à 0,1. Pour vous assurer d'atteindre cet objectif pour la plupart de vos utilisateurs, un seuil approprié à mesurer est le 75e centile des chargements de pages, segmenté en fonction des appareils mobiles et des ordinateurs.
Pour en savoir plus sur la recherche et la méthodologie derrière cette recommandation, consultez Définir les seuils des métriques Core Web Vitals.
Décalages de mise en page détaillés
Les décalages de mise en page sont définis par l'API Layout Instability, qui signale les entrées layout-shift
chaque fois qu'un élément visible dans la fenêtre d'affichage change de position de départ (par exemple, sa position supérieure et gauche en mode d'écriture par défaut) entre deux cadres. Ces éléments sont considérés comme des éléments instables.
Notez que les décalages de mise en page ne se produisent que lorsque les éléments existants changent de position de départ. Si un nouvel élément est ajouté au DOM ou qu'un élément existant change de taille, cela n'est pas comptabilisé comme un décalage de mise en page, tant que la modification n'entraîne pas le changement de position de départ des autres éléments visibles.
Score de décalage de mise en page
Pour calculer le score de décalage de mise en page, le navigateur examine la taille de la fenêtre d'affichage et le mouvement des éléments instables entre deux images affichées. Le score de décalage de mise en page est un produit de deux mesures de ce mouvement: la fraction d'impact et la fraction de distance (toutes deux définies ci-dessous).
layout shift score = impact fraction * distance fraction
Fraction d'impact
La fraction d'impact mesure l'impact des éléments instables sur la zone de la fenêtre d'affichage entre deux cadres.
La fraction d'impact d'un cadre donné combine les zones visibles de tous les éléments instables de ce cadre et du cadre précédent, exprimée sous la forme d'une fraction de la surface totale de la fenêtre d'affichage.
![Exemple de fraction d'impact avec un élément instable](https://web.developers.google.cn/static/articles/cls/image/impact-fraction-example-164341c82ee76.png?authuser=5&hl=fr)
Dans l'image précédente, un élément occupe la moitié de la fenêtre d'affichage dans un cadre. Ensuite, dans l'image suivante, l'élément se décale de 25% de la hauteur de la fenêtre d'affichage vers le bas. Le rectangle rouge en pointillé indique l'union de la zone visible de l'élément dans les deux cadres, qui, dans ce cas, représente 75% de la fenêtre d'affichage totale. Sa fraction d'impact est donc 0.75
.
Fraction de distance
L'autre partie de l'équation du score de décalage de la mise en page mesure la distance de déplacement des éléments instables par rapport à la fenêtre d'affichage. La fraction de distance correspond à la distance horizontale ou verticale la plus élevée que tout élément instable a déplacé dans l'image, divisée par la plus grande dimension de la fenêtre d'affichage (largeur ou hauteur, selon la valeur la plus élevée).
![Exemple de fraction de distance avec un élément instable](https://web.developers.google.cn/static/articles/cls/image/distance-fraction-example-9146d2a862482.png?authuser=5&hl=fr)
Dans l'exemple précédent, la plus grande dimension de la fenêtre d'affichage est la hauteur, et l'élément instable a été déplacé de 25% de la hauteur de la fenêtre d'affichage, ce qui donne une fraction de distance de 0,25.
Ainsi, dans cet exemple, la fraction d'impact est 0.75
et la fraction de distance est 0.25
. Le score de décalage de mise en page est donc 0.75 * 0.25 = 0.1875
.
Exemples
L'exemple suivant montre comment l'ajout de contenu à un élément existant affecte le score de décalage de mise en page:
![Exemple de décalage de mise en page avec plusieurs éléments stables et _instables_](https://web.developers.google.cn/static/articles/cls/image/layout-shift-example-mul-10d90b67b5d6a.png?authuser=5&hl=fr)
Dans cet exemple, la zone grise change de taille, mais sa position de départ ne change pas. Il ne s'agit donc pas d'un élément instable.
La boîte de dialogue "Click Me!" ne se trouvait pas auparavant dans le DOM. Sa position de départ ne change donc pas non plus.
La position de départ de la boîte verte change, mais comme elle a été partiellement déplacée en dehors de la fenêtre d'affichage, la zone invisible n'est pas prise en compte lors du calcul de la fraction d'impact. L'union des zones visibles de la boîte verte dans les deux cadres (illustrée par le rectangle rouge en pointillé) est identique à la zone du cadre vert dans le premier cadre, soit 50% de la fenêtre d'affichage. La fraction d'impact est 0.5
.
La fraction de la distance est illustrée par la flèche violette. La boîte verte a été déplacée d'environ 14% vers le bas de la fenêtre d'affichage. La fraction de distance est donc de 0.14
.
Le score de décalage de mise en page est de 0.5 x 0.14 = 0.07
.
L'exemple suivant montre comment plusieurs éléments instables affectent le score de décalage de mise en page d'une page:
![Exemple de décalage de mise en page avec des éléments stables et _instables_ et un rognage de la fenêtre d'affichage](https://web.developers.google.cn/static/articles/cls/image/layout-shift-example-sta-05cf93597fcee.png?authuser=5&hl=fr)
Dans le premier cadre de l'image précédente, il y a quatre résultats d'une requête API pour des animaux, triés par ordre alphabétique. Dans le deuxième frame, d'autres résultats sont ajoutés à la liste triée.
Le premier élément de la liste ("Chat") ne change pas de position de départ entre les images. Il est donc stable. De même, les nouveaux éléments ajoutés à la liste n'étaient pas présents dans le DOM auparavant. Leur position de départ ne change donc pas non plus. Mais les articles intitulés "Chien", "Cheval" et "Zèbre" tous déplacent leur position de départ, ce qui en fait des éléments instables.
Là encore, les rectangles en pointillés rouges représentent l'union de ces trois éléments instables. avant et après les zones, qui représentent ici environ 60% de la surface de la fenêtre d'affichage (fraction d'impact de 0.60
).
Les flèches représentent la distance entre les éléments instables et leur position de départ. Le "zèbre" , représenté par la flèche bleue, a été le plus déplacé (environ 30% de la hauteur de la fenêtre d'affichage). Dans cet exemple, la fraction de la distance est donc 0.3
.
Le score de décalage de mise en page est de 0.60 x 0.3 = 0.18
.
Décalages de mise en page attendus et inattendus
Les décalages de mise en page ne sont pas tous mauvais. En fait, de nombreuses applications Web dynamiques modifient fréquemment la position de départ des éléments sur la page. Un décalage de mise en page n'est mauvais que si l'utilisateur ne s'y attend pas.
Décalages de mise en page déclenchés par l'utilisateur
Les décalages de mise en page qui se produisent en réponse aux interactions de l'utilisateur (cliquer ou appuyer sur un lien, appuyer sur un bouton ou saisir du texte dans un champ de recherche, par exemple) sont généralement acceptables, à condition que le décalage se produise suffisamment près de l'interaction pour que la relation soit claire pour l'utilisateur.
Par exemple, si une interaction utilisateur déclenche une requête réseau dont l'exécution peut prendre un certain temps, il est préférable de créer immédiatement de l'espace et d'afficher un indicateur de chargement pour éviter un décalage de mise en page désagréable à la fin de la requête. Si l'utilisateur ne se rend pas compte que quelque chose est en cours de chargement ou n'a aucune idée du moment où la ressource sera prête, il peut essayer de cliquer sur un autre élément en attendant, ce qui pourrait sortir de sous lui.
L'indicateur hadRecentInput
sera défini pour les décalages de mise en page qui se produisent dans les 500 millisecondes après une entrée utilisateur. Ils pourront donc être exclus des calculs.
Animations et transitions
Les animations et les transitions, lorsqu'elles sont bien réalisées, sont un excellent moyen de mettre à jour le contenu de la page sans surprendre l'utilisateur. Tout décalage brusque et inattendu sur la page nuit presque toujours à l'expérience utilisateur. Toutefois, les contenus qui se déplacent progressivement et naturellement d'une position à l'autre peuvent souvent aider l'utilisateur à mieux comprendre ce qui se passe et à le guider entre les changements d'état.
Veillez à respecter les paramètres du navigateur prefers-reduced-motion
, car certains visiteurs du site peuvent constater des effets néfastes ou des problèmes d'attention liés aux animations.
La propriété CSS transform
vous permet d'animer des éléments sans déclencher de décalages de mise en page:
- Au lieu de modifier les propriétés
height
etwidth
, utiliseztransform: scale()
. - Pour déplacer des éléments, évitez de modifier les propriétés
top
,right
,bottom
ouleft
, et utilisez plutôttransform: translate()
.
Mesurer le CLS
Le CLS peut être mesuré en atelier ou sur le terrain, et il est disponible avec les outils suivants:
Outils de terrain
- Expérience utilisateur Chrome Rapport
- PageSpeed Insights
- Search Console (Core Web Vitals) rapport)
- Bibliothèque JavaScript
web-vitals
Outils de l'atelier
Mesurer les décalages de mise en page en JavaScript
Pour mesurer les décalages de mise en page en JavaScript, utilisez l'API Layout Instability.
L'exemple suivant montre comment créer un PerformanceObserver
pour consigner les entrées layout-shift
dans la console:
new PerformanceObserver((entryList) => {
for (const entry of entryList.getEntries()) {
console.log('Layout shift:', entry);
}
}).observe({type: 'layout-shift', buffered: true});
Mesurer le CLS en JavaScript
Pour mesurer le CLS en JavaScript, vous devez regrouper ces entrées layout-shift
inattendues dans des sessions et calculer la valeur de session maximale. Vous pouvez vous reporter au code source de la bibliothèque JavaScript web vitals
qui contient une implémentation de référence sur le calcul du CLS.
Dans la plupart des cas, la valeur CLS actuelle au moment du déchargement de la page correspond à la valeur CLS finale de cette page, mais il existe quelques exceptions importantes, comme indiqué dans la section suivante. La bibliothèque JavaScript web vitals
tient compte autant que possible de ces éléments, dans les limites des API Web.
Différences entre la métrique et l'API
- Si une page est chargée en arrière-plan ou si elle s'affiche en arrière-plan avant que le navigateur n'affiche du contenu, aucune valeur CLS ne doit être indiquée.
- Si une page est restaurée à partir du cache amélioré, sa valeur CLS doit être réinitialisée, car les utilisateurs considèrent qu'il s'agit d'une visite de page distincte.
- L'API ne signale pas les entrées
layout-shift
pour les décalages se produisant dans les iFrames, mais la métrique s'applique à l'expérience utilisateur de la page. Cela peut se traduire par une différence entre les formats CrUX et RUM. Vous devez en tenir compte pour mesurer correctement le CLS. Les sous-frames peuvent utiliser l'API pour signaler leurs entréeslayout-shift
au frame parent à des fins d'agrégation.
Outre ces exceptions, le CLS est complexe, car il mesure toute la durée de vie d'une page:
- Les utilisateurs peuvent garder un onglet ouvert pendant très longtemps (des jours, des semaines ou des mois). En fait, un utilisateur peut ne jamais fermer un onglet.
- Sur les systèmes d'exploitation mobiles, les navigateurs n'exécutent généralement pas de rappels de déchargement de page pour les onglets en arrière-plan. Il est donc difficile de signaler la "finalité" .
Pour gérer de tels cas, le CLS doit être signalé chaque fois qu'une page est en arrière-plan, et non pas chaque fois qu'elle est déchargée (l'événement visibilitychange
couvre ces deux scénarios). Les systèmes d'analyse recevant ces données devront ensuite calculer la valeur CLS finale sur le backend.
Plutôt que d'apprendre et de gérer vous-même tous ces cas, les développeurs peuvent utiliser la bibliothèque JavaScript web-vitals
pour mesurer le CLS, qui prend en compte tous les éléments mentionnés ci-dessus, à l'exception du cas iFrame:
import {onCLS} from 'web-vitals';
// Measure and log CLS in all situations
// where it needs to be reported.
onCLS(console.log);
Améliorer le CLS
Pour en savoir plus sur l'identification des décalages de mise en page sur le terrain et sur l'utilisation des données de test pour les optimiser, consultez notre guide sur l'optimisation du CLS.
Ressources supplémentaires
- Conseils de Google Publisher Tag pour minimiser le décalage de mise en page
- Understanding Cumulative Layout Shift de Annie Sullivan et Steve Kobes, #PerfMatters (2020)
Journal des modifications
Il arrive que des bugs soient découverts dans les API utilisées pour mesurer les métriques, et parfois dans les définitions des métriques elles-mêmes. Par conséquent, des modifications doivent parfois être apportées et elles peuvent apparaître sous forme d'améliorations ou de régressions dans vos rapports et tableaux de bord internes.
Pour vous aider, toutes les modifications apportées à l'implémentation ou à la définition de ces métriques seront affichées dans ce journal des modifications.
Si vous avez des commentaires concernant ces métriques, vous pouvez les envoyer dans le groupe Google "web-vitals-feedback".