Résolution des problèmes CLS dans un site Web de commerce électronique alimenté par Next.js (étude de cas)

Publié: 2022-03-10
Résumé rapide ↬ Cumulative Layout Shift est l'un des éléments les plus difficiles à déboguer. Dans cet article, nous passons en revue différents outils pour étudier CLS, quand les utiliser (et quand ne pas les utiliser) et des solutions à certains des problèmes CLS auxquels nous avons été confrontés sur notre site Web de commerce électronique basé sur Next.js.

Fairprice est l'une des plus grandes épiceries en ligne de Singapour. Nous recherchons en permanence des domaines d'opportunités pour améliorer l'expérience d'achat en ligne de l'utilisateur. La performance est l'un des aspects essentiels pour garantir à nos utilisateurs une expérience utilisateur agréable, quels que soient leurs appareils ou leur connexion réseau.

Il existe de nombreux indicateurs de performance clés (KPI) qui mesurent différents points au cours du cycle de vie de la page Web (tels que TTFB, domInteractive et onload ), mais ces métriques ne reflètent pas la façon dont l'utilisateur final vit la page.

Nous voulions utiliser quelques KPI qui correspondent étroitement à l'expérience réelle des utilisateurs finaux afin que nous sachions que si l'un de ces KPI ne fonctionne pas bien, cela aura un impact direct sur l'expérience de l'utilisateur final. Nous avons découvert que les mesures de performance centrées sur l'utilisateur étaient parfaitement adaptées à cette fin.

Il existe de nombreuses mesures de performance centrées sur l'utilisateur pour mesurer différents points du cycle de vie d'une page, tels que FCP, LCP, FID, CLS, etc. Pour cette étude de cas, nous allons principalement nous concentrer sur CLS.

CLS mesure le score total de tous les changements de mise en page inattendus qui se produisent entre le moment où la page commence à se charger et jusqu'à ce qu'elle soit déchargée.

"

Par conséquent, avoir une valeur CLS faible pour une page garantit qu'il n'y a pas de changements de mise en page aléatoires provoquant la frustration de l'utilisateur. Barry Pollard a écrit un excellent article approfondi sur CLS.

Comment nous avons découvert le problème CLS dans notre page produit

Nous utilisons Lighthouse et WebPagetest comme outils de test synthétiques de performance pour mesurer le CLS. Nous utilisons également la bibliothèque web-vitals pour mesurer le CLS pour de vrais utilisateurs. En dehors de cela, nous vérifions la section Google Search Console Core Web Vitals Report pour avoir une idée de tout problème CLS potentiel dans l'une de nos pages. Lors de l'exploration de la section du rapport, nous avons constaté que de nombreuses URL de la page de détail du produit avaient une valeur CLS supérieure à 0,1 , ce qui laisse entendre qu'un événement majeur de changement de mise en page s'y produisait.

Plus après saut! Continuez à lire ci-dessous ↓

Débogage d'un problème CLS à l'aide de différents outils

Maintenant que nous savons qu'il y a un problème CLS sur la page de détail du produit, l'étape suivante consistait à identifier quel élément en était la cause. Dans un premier temps, nous avons décidé d'effectuer des tests à l'aide d'outils de test synthétiques.

Nous avons donc fait fonctionner le phare pour vérifier s'il pouvait trouver un élément susceptible de déclencher un changement de disposition majeur, il a signalé CLS à 0,004, ce qui est assez bas.

CLS est .004
CLS a montré un résultat CLS faible de .004 . ( Grand aperçu )

La page de rapport Lighthouse comporte une section de diagnostic. Cela n'a pas non plus montré d'élément provoquant une valeur CLS élevée.

Page de rapport phare
Un aperçu de la page du rapport incluant les résultats de la contribution du CLS. ( Grand aperçu )

Ensuite, nous avons exécuté WebpageTest et décidé de vérifier la vue de la pellicule :

la vue pellicule
La vue pellicule montre toute image qui a un changement visuel et un changement de disposition avec une ligne pointillée jaune. ( Grand aperçu )

Nous trouvons cette fonctionnalité très utile car nous pouvons savoir quel élément à quel moment a provoqué le changement de mise en page. Mais lorsque nous avons exécuté le test pour voir si des changements de mise en page sont mis en évidence, rien n'a contribué à l'énorme LCS :

test pour voir quel élément à quel moment a provoqué un changement de mise en page
Vous pouvez savoir si des changements de mise en page ont eu lieu en jetant simplement un coup d'œil rapide sur les cadres. ( Grand aperçu )

La particularité de CLS est qu'il enregistre les scores de changement de mise en page individuels pendant toute la durée de vie de la page et les ajoute.

"

Remarque : La façon dont le CLS est mesuré a changé depuis juin 2021.

Étant donné que Lighthouse et WebpageTest n'ont pu détecter aucun élément déclenchant un changement majeur de mise en page, cela signifie qu'il se produisait après le chargement initial de la page, probablement en raison d'une action de l'utilisateur. Nous avons donc décidé d'utiliser l'extension Web Vitals Google Chrome car elle peut enregistrer CLS sur une page pendant que l'utilisateur interagit avec elle. Après avoir effectué différentes actions, nous avons constaté que le score de changement de mise en page augmentait lorsque l'utilisateur utilise la fonction d'agrandissement de l'image.

Pour vérifier si un changement de disposition se produit pendant que le survol de la souris est sur l'image, nous avons utilisé l'extrait de code ci-dessous de https://web.dev/cls/ qui ajoute console.log lorsque le changement de disposition se produit :

 let cls = 0; new PerformanceObserver((entryList) => { for (const entry of entryList.getEntries()) { if (!entry.hadRecentInput) { cls += entry.value; console.log('Current CLS value:', cls, entry); } }}).observe({type: 'layout-shift', buffered: true});

Après une enquête plus approfondie, nous avons constaté que l'ASDA était confrontée à un problème similaire et l'a soulevé pour le chrome.

Cause première

Sur la page de détail du produit, les utilisateurs peuvent déplacer la souris sur l'image du produit pour afficher une section agrandie de l'image côte à côte de l'image réelle du produit, car cette vidéo montre exactement de quoi nous parlons.

La fonction d'agrandissement d'image aide nos utilisateurs à obtenir l'apparence du produit et à s'assurer qu'il s'agit de la bonne variante du produit qu'ils souhaitent acheter.

Nous avons utilisé la bibliothèque de react-image zoom pour créer cette fonctionnalité d'agrandissement d'image.

Les bibliothèques d'agrandissement d'image ont généralement une lentille (un carré qui se déplace lorsque la souris se déplace dans l'image). Étant donné que cet objectif change sa position supérieure et gauche avec le mouvement de la souris, il est détecté comme un changement de disposition déclenchant CLS. Nous avons vérifié la page de la bibliothèque ainsi que d'autres bibliothèques de réaction similaires ( react-image-magnify , react-image-zoom , react-image-magnifiers ) et avons constaté qu'elles souffraient toutes du même problème CLS.

Comment nous l'avons réparé

Nous avons remarqué que react-image-zoom utilisait la bibliothèque js-image-zoom . Nous avons donc dû modifier la bibliothèque de js-image zoom pour résoudre le problème.

La solution est assez simple. Pendant que la souris se déplace sur l'image du produit, l'élément de lentille d'image se déplace en changeant sa position gauche et supérieure. Pour résoudre le problème, nous avons utilisé transform translate qui déplace l'élément vers un nouveau calque, c'est-à-dire que tout mouvement qui a lieu sur ce nouveau calque ne provoque plus de décalage de mise en page :

gérer le mouvement de la lentille en utilisant transform translate
( Grand aperçu )

J'ai également créé un PR pour le référentiel d'origine afin que les autres développeurs utilisant cette bibliothèque puissent se débarrasser du problème CLS.

création d'un PR pour le référentiel d'origine
PR créé pour aider à se débarrasser du problème CLS. ( Grand aperçu )

L'impact du changement

Une fois le code déployé en production, le CLS a été corrigé sur la page de détails du produit et le nombre de pages impactées par le CLS a été réduit de 98 % :

un graphique qui montre l'impact du changement.
transform a un avantage de performance sur la manipulation de position en utilisant left et top. ( Grand aperçu )

Depuis que nous avons utilisé transform , cela a également contribué à rendre l'image agrandie plus fluide pour les utilisateurs.

Note : Paul Irish a écrit un excellent article sur ce sujet.

Autres changements clés que nous avons apportés à CLS

Il y a aussi d'autres problèmes auxquels nous avons été confrontés à travers de nombreuses pages de notre site Web qui contribuent à CLS. Passons en revue ces éléments et composants et voyons comment nous avons essayé d'atténuer les changements de disposition qui en découlent.

  • Polices Web :
    Nous avons remarqué que le chargement tardif des polices provoque des frustrations pour les utilisateurs car le contenu clignote et entraîne également une certaine quantité de changements de mise en page. Pour minimiser cela, nous avons apporté quelques modifications :

    • Nous avons auto-hébergé les polices au lieu de les charger à partir d'un CDN tiers.
    • Nous préchargeons les polices.
    • Nous utilisons font-display optionnel.
  • Images:
    Une valeur de hauteur ou de largeur manquante dans l'image entraîne le décalage de l'élément après l'image une fois l'image chargée. Cela finit par devenir un contributeur majeur à CLS. Puisque nous utilisons Next.js, nous avons profité du composant d'image intégré appelé next/images . Ce composant intègre plusieurs bonnes pratiques liées aux images. Il est construit sur la balise HTML <img> et peut aider à améliorer LCP et CLS. Je recommande fortement de lire cette RFC pour découvrir les principales caractéristiques et les avantages de son utilisation.

  • DEFILEMENT infini:
    Sur notre site Web, les pages de liste de produits ont un défilement infini. Ainsi, initialement, lorsque les utilisateurs font défiler vers le bas de la page, ils voient un pied de page pendant une fraction de seconde avant que le prochain ensemble de données ne soit chargé, cela provoque des changements de mise en page. Pour résoudre ce problème, nous avons pris quelques mesures :

    • Nous appelons l'API pour charger les données avant même que l'utilisateur n'atteigne le bas absolu de la liste.
    • Nous avons réservé suffisamment d'espace pour l'état de chargement et nous montrons des squelettes de produits pendant l'état de chargement. Alors maintenant, lorsque l'utilisateur fait défiler, il ne voit pas le pied de page pendant une fraction de seconde pendant que les produits sont chargés.

Addy Osmani a écrit un article détaillé sur cette approche que je recommande vivement de consulter.

Points clés à retenir

  • Bien que Lighthouse et WebpageTest aident à découvrir les problèmes de performances qui se produisent jusqu'au chargement de la page, ils ne peuvent pas détecter les problèmes de performances après le chargement de la page.
  • Les extensions Web Vitals peuvent détecter les modifications CLS déclenchées par les interactions de l'utilisateur. Ainsi, si une page a une valeur CLS élevée mais que Lighthouse ou WebpageTest signale un CLS faible, l'extension Web Vitals peut aider à identifier le problème.
  • Les données de Google Search Console sont basées sur les données d'utilisateurs réels, ce qui peut également indiquer des problèmes de performances potentiels survenant à tout moment du cycle de vie d'une page. Une fois qu'un problème est détecté et résolu, le fait de vérifier à nouveau la section du rapport peut aider à vérifier l'efficacité du correctif de performances. Les modifications sont reflétées en quelques jours dans la section du rapport Web Vitals.

Dernières pensées

Bien que les problèmes CLS soient comparativement plus difficiles à déboguer, l'utilisation d'une combinaison de différents outils jusqu'au chargement de la page (Lighthouse, WebPageTest) et de l'extension Web Vitals (après le chargement de la page) peut nous aider à identifier le problème. C'est également l'une des mesures qui fait l'objet de nombreux développements actifs pour couvrir un large éventail de scénarios, ce qui signifie que la façon dont elle est mesurée va changer à l'avenir. Nous suivons https://web.dev/evolving-cls/ pour connaître les changements à venir.

Quant à nous, nous travaillons continuellement à l'amélioration d'autres Core Web Vitals. Récemment, nous avons mis en place un préchargement d'image réactif et commencé à diffuser des images au format WebP, ce qui nous a aidés à réduire de 75 % la charge utile des images, à réduire le LCP de 62 % et l'indice de vitesse de 24 %. Vous pouvez lire plus de détails sur l'optimisation pour améliorer le LCP et l'indice de vitesse ou suivre notre blog d'ingénierie pour connaître d'autres travaux passionnants que nous réalisons.

Nous tenons à remercier Alex Castle de nous avoir aidés à déboguer le problème CLS sur la page du produit et à résoudre les problèmes dans l'implémentation next/images .