Fermer

octobre 18, 2021

Résoudre les problèmes de CLS dans un site Web de commerce électronique basé sur Next.js (étude de cas) —5 minutes de lecture



Résumé rapide ↬

Cumulative Layout Shift est l'un des noyaux Web les plus difficiles à déboguer. Dans cet article, nous passons en revue différents outils pour enquêter sur CLS, quand les utiliser (ou non) 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. Les performances sont 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 comme TTFB, domInteractive et onload), mais ces métriques ne reflètent pas la façon dont l'utilisateur final perçoit 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 métriques de performances centrées sur l'utilisateur étaient parfaitement adaptées à cet objectif.

Il existe de nombreuses métriques de performances centrées sur l'utilisateur pour mesurer différents points du cycle de vie d'une page, telles 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 début du chargement de la page et son déchargement.

Par conséquent, le fait d'avoir une faible valeur CLS pour une page garantit qu'il n'y a pas de décalage de mise en page aléatoire provoquant la frustration de l'utilisateur. Barry Pollard a écrit un excellent article détaillé 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étique 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. En explorant la section du rapport, nous avons découvert que de nombreuses URL de la page de détail du produit avaient plus de 0.1 valeur CLS, ce qui laisse supposer qu'il y a un événement majeur de changement de mise en page.

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

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 l'élément qui en était la cause. Au début, nous avons décidé d'exécuter des tests à l'aide d'outils de test synthétiques. 004 qui est assez bas.

 CLS est .004

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

La page du rapport Lighthouse comporte une section de diagnostic. Cela n'a également montré aucun élément provoquant une valeur CLS élevée.

Page de rapport Lighthouse

Un aperçu de la page de rapport comprenant les résultats de la contribution CLS. ( Grand aperçu)

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

la vue de la pellicule

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

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

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 été modifiée depuis juin 2021.

Depuis que Lighthouse et WebpageTest n'ont pu détecter aucun élément ayant déclenché un changement de mise en page majeur, ce qui 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 décalage de mise en page augmente lorsque l'utilisateur utilise la fonction d'agrandissement de l'image. https://web.dev/cls/ qui ajoute console.log lorsque le changement de mise en page se produit :

let cls = 0 ;

new PerformanceObserver((entryList) => {
 for (entrée constante de entryList.getEntries()) {
   if (!entry.hadRecentInput) {
     cls += entrée.valeur;
     console.log('Valeur CLS actuelle :', cls, entrée);
   }
 }}).observe({type: 'layout-shift', buffered: true});

Au cours d'une enquête plus approfondie, nous avons constaté qu'ASDA faisait face à un problème similaire et l'a soulevé pour Chrome.

Cause racine

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

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

Nous avons utilisé react-image zoom bibliothèque 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 de position supérieure et gauche avec le mouvement de la souris, il est détecté comme un décalage de mise en page 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-magnifyreact-image-zoomreact-image-magnifiers) et ont constaté que tous souffrent du même problème CLS. ]une bibliothèque. Nous avons donc dû modifier la bibliothèque 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 l'objectif en en utilisant transform translate

( Grand aperçu)

J'ai également créé un PR vers 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 vers le référentiel d'origine

PR créé pour aider à se débarrasser du problème CLS. ( Grand aperçu)

L'impact du changement

Après le déploiement du code en production, le CLS a été corrigé sur la page des détails du produit et le nombre de pages impactées par CLS a été réduit de 98 % :

un graphique qui montre le l'impact du changement.

transform a un avantage de performance par rapport à la manipulation de position en utilisant left et top. ( Grand aperçu)

Puisque nous avons utilisé transformcela a également contribué à faire en sorte que l'image magnifie une expérience plus fluide pour les utilisateurs.

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

Autres modifications clés que nous avons apportées à CLS

Il existe également d'autres problèmes auxquels nous avons été confrontés dans 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 mise en page qui en découlent. quantité de décalages 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 en option.
  • Images :
    Une valeur de hauteur ou de largeur manquante dans l'image provoque le décalage de l'élément après l'image une fois que l'image est 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 à l'image. Il est construit sur la balise HTML et peut aider à améliorer LCP et CLS. Je recommande fortement de lire cette RFC pour découvrir les principales caractéristiques et avantages de son utilisation.

  • Infinite Scroll :
    Sur notre site Web, les pages de liste de produits ont un défilement infini. Ainsi, au départ, lorsque les utilisateurs défilent 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 suivi quelques étapes :

    • 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 le chargement. statut. 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 fortement de vérifier .

    Principaux points à retenir

    • Bien que Lighthouse et WebpageTest aident à détecter les problèmes de performances se produisant 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, donc si une page a une valeur CLS élevée, mais Lighthouse ou WebpageTest signale un CLS faible, alors l'extension Web Vitals peut aider à identifier le problème. à tout moment du cycle de vie d'une page. Une fois qu'un problème est détecté et résolu, vérifier à nouveau la section du rapport peut aider à vérifier l'efficacité du correctif de performance. Les modifications sont reflétées en quelques jours dans la section du rapport Web Vitals.

    Réflexions finales

    Bien que les problèmes CLS soient comparativement plus difficiles à déboguer, en utilisant une combinaison de différents outils jusqu'au chargement de la page (Lighthouse, WebPageTest) et l'extension Web Vitals (après chargement de la page) peut nous aider à identifier le problème. C'est également l'une des métriques 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 être informés de tout changement à venir.

    Quant à nous, nous travaillons également en permanence à l'amélioration d'autres Core Web Vitals. Récemment, nous avons implémenté un préchargement d'image réactif et commencé à diffuser des images au format WebP, ce qui nous a permis de réduire de 75 % la charge utile des images, de réduire le LCP de 62 % et l'indice de vitesse de 24 %. Vous pouvez lire plus de détails sur l'optimisation pour l'amélioration du LCP et de l'indice de vitesse ou suivre notre blog d'ingénierie pour en savoir plus sur d'autres travaux passionnants que nous effectuons.

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

    Smashing Editorial" width="35" height= "46" loading="lazy" decoding="async(vf, yk, il)






    Source link

    0 Partages