Fermer

juin 2, 2021

Améliorer les performances d'une boutique en ligne (étude de cas) —


À propos de l'auteur

Jennifer Brehm porte plusieurs chapeaux chez ilscipio qu'elle a aidé à fonder : Frontend, backend et management. Mais son cœur appartient au puzzle logique qu'est CSS.
En savoir plus sur
Jennifer

Obtenir un bon score de performance de Google est difficile pour n'importe quel site Web, mais le faire pour une boutique en ligne est encore plus difficile. Nous avons obtenu des scores verts, voire plusieurs pour mobile. Voici comment nous avons procédé.

Chaque développeur front-end recherche le même Saint Graal de la performance : les scores verts dans Google Page Speed. Les signes tangibles du travail bien fait sont toujours appréciés. Comme la chasse au Graal, cependant, vous devez vous demander si c'est vraiment la réponse que vous recherchez. Les performances réelles pour vos utilisateurs et la façon dont le site Web « se sent » lorsque vous l'utilisez ne doivent pas être réduits, même si cela vous coûte un ou deux points en vitesse de page (sinon, nous avoir une barre de recherche et du texte sans style).

Je travaille dans une petite agence numérique et mon équipe travaille principalement sur de grands sites Web et magasins d'entreprise – la vitesse de la page entre en ligne de compte à un moment donné, mais généralement à ce moment-là, la réponse est qu'une réécriture énorme serait nécessaire pour vraiment réaliser n'importe quoi, un effet secondaire malheureux de la taille et de la structure des projets dans les entreprises.

Travailler avec Jewellerybox sur sa boutique en ligne était un changement de rythme bienvenu pour nous. Le projet consistait à mettre à niveau le logiciel de la boutique vers notre propre système open source et à refaire le front-end de la boutique à partir de zéro. Le design a été réalisé par une agence de design et UX qui a également géré le prototype HTML (basé sur Bootstrap 4). À partir de là, nous l'avons incorporé dans les modèles – et pour une fois, nous avions également un client obsédé par les performances du site Web.

Pour le lancement, nous nous sommes principalement concentrés sur la sortie du nouveau design, mais une fois le site Web la relance a été mise en ligne, nous avons commencé à concentrer notre attention sur la transformation des scores rouges et oranges en verts. Ce fut un voyage de plusieurs mois plein de décisions difficiles, avec de nombreuses discussions sur les optimisations qui valaient la peine d'être poursuivies. Aujourd'hui, le site Web est beaucoup plus rapide et se classe très bien dans diverses vitrines et références. Dans cet article, je vais mettre en évidence une partie du travail que nous avons effectué et comment nous avons pu atteindre notre vitesse.

Ce rapport mobile Lighthouse pour la première page a montré qu'il restait beaucoup de travail à faire.
Ceci Le rapport sur le mobile de Lighthouse pour la page d'accueil a montré qu'il restait beaucoup de travail à faire. ( Grand aperçu)

Les magasins en ligne sont un peu différents

Avant d'entrer dans les détails, prenons un court instant pour expliquer en quoi les magasins en ligne sont différents de nombreux autres sites Web (si vous savez déjà cela, nous vous retrouverons dans la section suivante). Lorsque nous parlons d'un site Web de commerce électronique, les pages principales que vous aurez sont :

  • la page d'accueil (et les pages de « contenu »),
  • les pages de catégories et de recherche,
  • les pages de détails des produits,[19659014]le panier et la caisse (évidemment).

Pour cet article, nous allons nous concentrer sur les trois premiers et les ajustements de performances pour ceux-ci. La caisse est sa propre bête. Là, vous aurez beaucoup de JavaScript et de logique back-end supplémentaires pour calculer les prix, ainsi que plusieurs appels de service pour obtenir le fournisseur d'expédition approprié et des estimations de prix en fonction du pays vers lequel vous expédiez.

Ceci est évidemment en plus du validation des champs des formulaires dont vous aurez besoin pour enregistrer les adresses de facturation et de livraison. Ajoutez à cela le drop-in du fournisseur de paiement, et vous avez vous-même des pages que personne ne voudra toucher une fois qu'elles auront été correctement testées et fonctionneront.

 La page d'accueil est modifiable via le CMS et comporte de nombreuses images et carrousels.
La page d'accueil est modifiable via le CMS et comporte de nombreuses images et carrousels. ( Grand aperçu)
 Une version de la page de détail du produit avec tout : choisissez une taille, ajoutez-y des gravures, peut-être changez la couleur.
Une version de la page de détail du produit avec tout : choisissez une taille, ajoutez-y des gravures, changez peut-être la couleur. ( Grand aperçu)

Quelle est la première chose à laquelle vous pensez lorsque vous imaginez une boutique en ligne ? Images — beaucoup, beaucoup d'images de produits. Ils sont pratiquement partout et domineront votre conception. De plus, vous voudrez montrer de nombreux produits pour amener les gens à acheter chez vous – il s'agit donc d'un carrousel. Mais attendez! Les gens cliquent-ils sur les produits qu'il contient ? Nous pouvons le découvrir en mettant un peu de suivi sur le carrousel. Si nous le suivons, nous pouvons l'optimiser ! Et soudain, nous avons des carrousels de produits externes alimentés par l'IA sur nos pages.

Le fait est qu'un carrousel ne sera pas le dernier élément pénalisant pour la vitesse que vous ajouterez à la page pour présenter plus de produits dans l'espoir d'en attirer plus. Ventes. Bien sûr, une boutique a besoin d'éléments interactifs qu'il s'agisse d'un zoom sur l'image du produit, de quelques vidéos, d'un compte à rebours jusqu'à la date limite d'expédition d'aujourd'hui ou d'une fenêtre de discussion pour contacter le service client. Tous ces éléments sont très importants lorsque vous mesurez les conversions directement en tant que revenus. De plus, tous les quelques mois, un membre de l'équipe repérera de nouvelles fonctionnalités intéressantes qui pourraient être ajoutées, et ainsi la complexité et le JavaScript commencent à s'accumuler, même si vous avez commencé avec les meilleures intentions pour le garder léger.

Et alors que vous pouvez généralement mettre en cache la page entière d'un article, il n'en va pas de même pour de nombreuses pages et éléments de boutique. Certaines sont spécifiques à l'utilisateur, comme le panier dans l'en-tête ou la liste de souhaits, et en raison de la nature personnelle des données, elles ne doivent jamais être mises en cache. De plus, si vous avez des biens physiques, vous avez affaire à un inventaire en direct : pendant la ruée de Noël en particulier, vous aurez besoin que les informations sur l'inventaire soient précises et à jour ; vous aurez donc besoin d'une stratégie de mise en cache plus complexe qui vous permet de mettre en cache des parties de la page et de tout combiner lors du rendu côté serveur.

Mais même dans les phases de planification, des pièges vous attendent. . Dans une conception – et souvent aussi la phase de prototype – vous travaillerez avec des noms et des descriptions de produits finement conçus, tous de longueur presque uniforme et des images de produits idéales. Ils ont l'air incroyable ! Le seul problème? En réalité, les informations sur le produit peuvent être de longueur très différente ce qui peut gâcher votre conception. Avec plusieurs milliers de produits, vous ne pouvez pas vérifier chacun. Par conséquent, il est utile que les concepteurs ou les personnes réalisant le test du prototype avec des chaînes très courtes et très longues pour s'assurer que la conception s'adapte toujours. De même, faire apparaître des informations deux fois dans le HTML, une fois pour le bureau et une fois pour le mobile, peut être un énorme problème pour une boutique, surtout s'il s'agit d'informations complexes comme les détails du produit, le panier ou les facettes des filtres sur une catégorie de produits. page. Il est difficile de les synchroniser – alors, s'il vous plaît, aidez un autre développeur et ne le faites pas.

Une autre chose qui ne devrait jamais être une réflexion après coup et qui devrait être intégrée à partir du stade du prototype est l'accessibilité. Plusieurs outils peuvent vous aider avec certaines des basesd'avoir un texte alternatif pour toutes les images et icônes avec une fonction, au contraste des couleurs, à savoir quels attributs ARIA utiliser où (et quand ne pas le faire). Intégrer cela dès le début est beaucoup plus facile que plus tard, et cela permet à tout le monde de profiter du site Web sur lequel vous travaillez. Voici un conseil : si vous n'avez pas vu de personnes utiliser un lecteur d'écran ou naviguer avec un simple clavier, des vidéos à ce sujet peuvent être facilement trouvées sur YouTube. Cela changera votre compréhension de ces sujets.

Retour aux performances : Pourquoi est-il si important d'améliorer les performances d'un magasin ? La réponse évidente est que vous voulez que les gens achètent chez vous . Vous pouvez affecter cela de plusieurs manières, et la vitesse de votre site Web est importante. Des études montrent que chaque seconde supplémentaire de temps de chargement a un impact significatif sur le taux de conversion. De plus, la vitesse de la page est un facteur de classement pour la recherche et également pour vos annonces Google. Ainsi, l'amélioration des performances aura un effet tangible sur les résultats.

Practical Things We Did

Certains goulots d'étranglement des performances sont faciles à identifier, mais une amélioration en profondeur est un voyage plus long, avec de nombreux rebondissements. Nous avons commencé avec toutes les choses habituelles, telles que revérifier la mise en cache des ressources, voir ce que nous pouvions précharger ou charger de manière asynchrone, nous assurer que nous utilisons HTTP/2 et TLSv1.3. Beaucoup d'entre eux sont couverts dans  Aperçu utile de CSS-Trickset Smashing Magazine propose une excellente  liste de contrôle PDF.

First Things First : Things Loaded On All Pages

Let's parler de ressources, et pas seulement CSS ou JavaScript (que nous aborderons plus tard). Nous avons commencé par examiner les éléments partagés sur plusieurs écrans, chacun pouvant avoir un impact. Ce n'est qu'après cela que nous nous sommes concentrés sur les types de pages et les problèmes qui leur sont propres. Certains éléments courants étaient les suivants.

Chargement d'icônes

Comme sur tant de sites Web, nous utilisons plusieurs icônes dans notre conception. Le prototype est venu avec des icônes personnalisées qui ont été intégrées Symboles SVG. Ceux-ci étaient stockés sous la forme d'une grande balise svg dans l'en-tête HTML de la page, avec un symbole pour chacune des icônes qui était ensuite utilisé comme lien svg dans le corps du code HTML. Cela a le bon effet de les rendre directement disponibles pour le navigateur lorsque le document se charge, mais évidemment le navigateur ne peut pas les mettre en cache pour l'ensemble du site Web. Nous avons donc décidé de les déplacer vers un fichier SVG externe et de le précharger. De plus, nous n'avons inclus que les icônes que nous utilisons réellement. De cette façon, le fichier peut être mis en cache sur le serveur et dans le navigateur, et aucun SVG superflu n'aura besoin d'être interprété. Nous prenons également en charge l'utilisation de Font Awesome sur la page (que nous chargeons via JavaScript), mais nous la chargeons à la demande (en ajoutant un petit script qui vérifie les balises, puis en chargeant la police JavaScript impressionnant pour obtenir toutes les icônes SVG qu'il trouve). Parce que nous nous en tenons à nos propres icônes au-dessus du pli, nous pouvons exécuter l'intégralité du script après le chargement du DOM.

Nous utilisons également des emoji à certains endroits pour les icônes colorées, ce à quoi aucun d'entre nous n'a vraiment pensé mais ce que notre éditeur de contenu, Daena, a demandé et qui sont un excellent moyen d'afficher des icônes sans aucun effet négatif sur les performances (le seul inconvénient étant les différentes conceptions sur différents systèmes d'exploitation).

Chargement des polices

J'aime sur tant d'autres sites Web, nous utilisons des polices Web pour nos besoins en matière de typographie. La conception nécessite deux polices dans le corps (Josefin Sans en deux graisses), une pour les titres (Nixie One) et une pour le texte spécialement stylisé (Moonstone Regular). Dès le début, nous les avons stockées localement, avec un réseau de diffusion de contenu (CDN) pour les performances, mais après avoir lu le merveilleux article de Simon Hearne sur éviter les changements de mise en page avec le chargement des polices nous avons expérimenté la suppression de la version en gras et en utilisant la normale.

Dans nos tests, la différence visuelle était si faible qu'aucun de nos testeurs n'a été capable de dire sans voir les deux en même temps. Ainsi, nous avons supprimé le poids de la police . En travaillant sur cet article et en préparant une aide visuelle pour cette section, nous sommes tombés sur de plus grandes différences entre les navigateurs basés sur Chromium sur Mac et ceux basés sur WebKit sur les écrans haute résolution (yay, complexité !). Cela a conduit à une autre série de discussions sur ce que nous devrions faire.

Après quelques allers-retours, nous avons choisi de garder le faux gras et d'utiliser -webkit-text-stroke: 0.3px pour aider ces particuliers navigateurs. La différence par rapport à l'utilisation de l'épaisseur de police distincte réelle est légère, mais pas suffisante pour notre cas d'utilisation, où nous n'utilisons presque aucune police en gras, seulement une poignée de mots à la fois (désolé, amateurs de polices).

Voir le stylo [Jewellerybox Case Study (Example #1)](https://codepen.io/smashingmag/pen/MWprwyE) par Pfenya.

Voir le stylo Jewellerybox Case Study (Example #1) par Pfenya.

De plus, plusieurs produits peuvent être personnalisés avec des gravures. Ces gravures peuvent être réalisées dans plusieurs polices, et pour certaines nous proposons un aperçu avec la police appliquée. Pour ceux-ci, nous téléchargeons la police à la demande lorsqu'elle est choisie dans le sélecteur de police déroulant. Les aperçus dans la liste déroulante sont des exemples d'images de ce à quoi ressemble la police. Cela nous évite d'avoir à télécharger 10 fichiers de polices supplémentaires ou plus.

Legacy Support

Un jour, CSS-Tricks m'a surpris avec un article sur "Comment Favicon en 2021". Nous utilisions toutes les tailles d'icônes tactiles dans le monde – l'article m'a fait réévaluer ce dont nous avons réellement besoin et m'a montré que parfois ce qui était vrai il y a quelques années pouvait ne plus être nécessaire. Sur la base de l'article, nous avons limité nos listes de favicon et d'icônes tactiles aux versions recommandées.

De même, nous avons également converti une police que nous avions uniquement en tant que version WOFF en WOFF2, qui est beaucoup plus petite, et nous avons décidé de fournir WOFF2 pour les polices (avec WOFF restant comme solution de secours). Et nous avons purgé les directives CSS qui ne sont plus nécessaires.

Lazy And On-Demand Loading

Plusieurs métriques se concentrent sur le temps après lequel les utilisateurs peuvent interagir avec la page. La logique veut qu'avoir moins d'éléments à charger signifie que ce point sera atteint plus tôt. Pour en tenir compte, il est important de se demander quelles parties de la page sont essentielles et dont l'utilisateur n'aura besoin que plus tard. Nous avons eu beaucoup de débats et d'essais et d'erreurs à ce sujet. La cascade de l'activité du réseau a beaucoup aidé ici, tout comme la réflexion sur les flux d'utilisateurs. Par exemple, l'image du produit agrandie peut être chargée la première fois qu'un utilisateur interagit avec l'image du produit, et les images dans le pied de page ne s'affichent généralement pas au-dessus du pli et peuvent être chargées plus tard. Si vous êtes préoccupé par les ralentissements, vous pouvez toujours travailler avec la prélecture des ressources.

Une chose que nous avons remarquée très tôt était le gros impact du client de chat. C'était plus de 500 Ko de JavaScript seul, et même si je n'ai malheureusement plus de graphique, il était également lent à charger. Même si JavaScript était configuré pour se charger de manière asynchrone, Google l'incluait dans les mesures du délai d'interaction. Nous n'avons pas été en mesure de déterminer complètement pourquoi c'était le cas, mais entre cela et sa taille, nous avons commencé à chercher des alternatives, au lieu d'essayer de réparer quelque chose sur lequel nous avions un contrôle limité. Nous avons convaincu Jewellerybox d'essayer à la place un widget de chat open source auto-hébergé, ce qui nous donne plus de contrôle sur la façon dont il est chargé et qui est aussi beaucoup plus petit. Pour l'améliorer encore, nous ne chargeons initialement que l'icône du chat ; le reste est chargé lorsque vous cliquez pour l'ouvrir.

Jewellerybox voulait essayer un service tiers qui utilise IA pour améliorer la personnalisation des produits dans les carrousels sur plusieurs pages. Nous avons décidé d'appeler son API depuis le back-end pour cela, afin d'avoir plus de contrôle sur ce qui est chargé (sans grandes dépendances JavaScript) et combien de temps nous attendons une réponse de leur service (avec quelques solutions de secours définies). Pour cette raison, les carrousels se chargent de la même manière que les non personnalisés et peuvent également être mis en cache avec une clé de cache unique.

 Il s'agit d'un carrousel tiers mais il ressemble et se charge comme celui par défaut.
]Il s'agit d'un carrousel tiers, mais il ressemble et se charge comme celui par défaut. ( Grand aperçu)

Il existe cependant un inconvénient : cela signifie que le rendu initial de la page côté serveur peut être plus lent s'il n'est pas mis en cache. Pour cette raison, nous travaillons actuellement sur d'autres moyens d'injecter les résultats après le chargement de la page et d'afficher un espace réservé dans un premier temps.

Deuxièmement : Optimiser JavaScript – Une bataille difficile contre les ennemis externes

Le carrousel nous amène à le deuxième grand domaine sur lequel nous nous sommes concentrés : JavaScript. Nous avons audité le JavaScript dont nous disposions, et la majorité provient de bibliothèques pour différentes tâches, avec très peu de code personnalisé. Nous avons optimisé le code que nous avions écrit nous-mêmes, mais il est évident que vous ne pouvez pas faire grand-chose s'il ne s'agit que d'une fraction de votre code global – les gros gains résident dans les bibliothèques.

Optimiser les éléments dans les bibliothèques ou retirer des pièces dont vous n'avez pas besoin est, selon toute vraisemblance, une course de fou. Vous ne savez pas vraiment pourquoi certaines pièces sont là, et vous ne pourrez plus jamais mettre à niveau la bibliothèque sans beaucoup de travail manuel. Dans cet esprit, nous avons pris du recul et regardé quelles bibliothèques nous utilisons et pour quoi nous en avons besoin et nous avons recherché pour chacune s'il existe une alternative plus petite ou plus rapide qui correspond tout aussi bien à nos besoins. .

Dans plusieurs cas, il y en a eu ! Par exemple, nous avons décidé de remplacer la bibliothèque de curseurs Slick par GliderJSqui a moins de fonctionnalités mais toutes celles dont nous avons besoin, est plus rapide à charger et a un support CSS plus moderne ! De plus, nous avons retiré de nombreuses bibliothèques autonomes du fichier JavaScript principal et avons commencé à les charger à la demande.

Étant donné que nous utilisons Bootstrap 4, nous incluons toujours jQuery pour le projet, mais nous travaillons à tout remplacer. avec des implémentations natives. Pour Bootstrap lui-même, il existe une version bootstrap.native sur GitHub sans la dépendance jQuery que nous utilisons maintenant. Il est plus petit et fonctionne plus rapidement. De plus, nous générons deux versions de notre fichier JavaScript principal : une sans polyfills et une avec eux inclus, et nous échangeons la version avec eux lorsque le navigateur en a besoin, ce qui nous permet de fournir une version principale simplifiée à la plupart des gens. Nous avons testé un service de « polyfill-on-demand », mais les performances n'ont pas été à la hauteur de nos attentes.

Une dernière chose au sujet de jQuery. Initialement, nous l'avons chargé depuis notre serveur. Nous avons constaté des améliorations des performances sur notre système de test lors du chargement via le CDN de Google, mais Page Speed ​​Insights s'est plaint des performances (je me demande qui pourrait résoudre ce problème), nous avons donc testé à nouveau l'hébergement nous-mêmes et en production. était en fait plus rapide en raison du CDN que nous utilisons.

Leçon apprise : un environnement de test n'est pas un environnement de production, et les correctifs pour l'un peuvent ne pas s'appliquer à l'autre.

Troisième étape : Images — Les formats, les tailles et tout ce qui est jazz

Les images sont une partie importante de ce qui fait une boutique en ligne. Une page contiendra généralement plusieurs dizaines d'images, avant même de compter les différentes versions pour différents appareils. Le site Web de la boîte à bijoux existe depuis près de 10 ans et de nombreux produits sont disponibles depuis la majeure partie de cette période, de sorte que les images originales des produits ne sont pas uniformes en taille et en style, et le nombre de photos de produits peut également varier.

Idéalement. , nous aimerions proposer des images réactives pour différentes tailles de vue et densités d'affichage dans des formats modernes, mais tout changement dans les exigences impliquerait un travail de conversion important. Pour cette raison, nous utilisons actuellement une taille optimisée des images de produits, mais nous n'avons pas d'images réactives pour eux. La mise à jour est sur la feuille de route mais pas anodine. Les pages de contenu offrent plus de flexibilité, et là, nous générons et utilisons différentes tailles et incluons à la fois les formats WebP et de secours.

Avoir autant d'images ajoute beaucoup de poids à la charge utile initiale. Ainsi, quand et comment charger des images est devenu un sujet énorme. Le chargement paresseux semble être la solution, mais s'il est appliqué de manière universelle, il peut ralentir les images initialement visibles, plutôt que de les charger directement (ou du moins c'est ce que l'utilisateur ressent). Pour cette raison, nous avons opté pour une combinaison de chargement des premiers directement et de lazy-loading du reste, en utilisant une combinaison de native lazy-loading et d'un script.

Pour le logo du site, nous utilisons un fichier SVG dont nous avons obtenu une première version du client. Le logo est une police complexe dans laquelle des parties des lettres sont manquantes, car elles seraient dans une impression imparfaite faite à la main. Dans les grandes tailles, vous auriez besoin d'afficher les détails, mais sur le site Web, nous ne l'utilisons jamais au-dessus de 150 par 30 pixels. Le fichier original faisait 192 Ko, pas énorme mais pas super petit non plus. Nous avons décidé de jouer avec le SVG et de réduire les détails, et nous nous sommes retrouvés avec une version de 40 Ko décompressée. Il n'y a pas de différence visuelle dans les tailles d'écran que nous utilisons.

Pouvez-vous repérer une différence significative, même à cette taille plus grande ?
Pouvez-vous repérer une différence significative, même à cette taille plus grande ? ( Grand aperçu)

Dernier mais certainement pas le moindre : CSS

Critical CSS

CSS figure énormément dans le Chrome User Experience Report (CrUX) de Google et est également très présent dans le rapport et les recommandations de Google Page Speed ​​Insights. L'une des premières choses que nous avons faites a été de définir un CSS critique, que nous chargeons directement dans le HTML afin qu'il soit disponible pour le navigateur dès que possible – c'est votre arme principale pour lutter contre les changements de mise en page du contenu (CLS). Nous avons opté pour une combinaison d'extraction automatisée du CSS critique basée sur une page prototype et un mécanisme avec lequel nous pouvons définir des noms de classes à extraire (y compris toutes les sous-règles). Nous le faisons séparément pour les styles généraux, les styles de page de produit et les styles de catégorie qui sont ajoutés aux types de page respectifs.

Quelque chose que nous avons appris de cela et qui a causé quelques bogues entre les deux, c'est que nous devons faire attention à ce que l'ordre de CSS n'est pas modifié par cela. Entre différentes personnes qui écrivent le code, quelqu'un qui ajoute un remplacement plus tard dans le fichier et un outil automatique qui extrait des éléments, cela peut devenir compliqué.

Dimensions explicites contre CLS

Pour moi, CLS est quelque chose que Google a sorti de son chapeau. , et maintenant nous devons tous nous en occuper et nous en occuper collectivement. Alors qu'auparavant, nous pouvions simplement laisser les conteneurs obtenir leur taille à partir des éléments qu'ils contiennent, maintenant le chargement de ces éléments peut perturber la taille de la boîte. Dans cet esprit, nous avons utilisé l'onglet "Performances" dans les outils de développement et le générateur de GIF très utile Layout Shift pour voir quels éléments sont à l'origine du CLS. À partir de là, nous avons examiné non seulement les éléments eux-mêmes, mais aussi leurs parents et analysé les propriétés CSS qui auraient un impact sur la mise en page. Parfois, nous avons eu de la chance – par exemple, le logo avait juste besoin d'une taille explicite définie sur le mobile pour éviter un changement de mise en page – mais d'autres fois, la lutte était réelle.

Conseil de pro : Parfois, un changement est provoqué. non par l'élément apparent, mais par l'élément qui le précède. Pour identifier les coupables possibles, concentrez-vous sur les propriétés qui changent de taille et d'espacement. La question de base à vous poser est : Qu'est-ce qui pourrait provoquer le déplacement de ce bloc ?

 Exemple de décalage CLS que nous avons vu — toutes les cases du contenu ont été causées par l'angle de « Nouvelle collection »
Exemple de le changement CLS que nous avons vu – toutes les cases du contenu ont été causées par l'angle de "Nouvelle collection". ( Grand aperçu)

Parce que tant d'images sont sur la page, les faire se comporter correctement avec CLS nous a également causé du travail. Barry Pollard nous le rappelle à juste titre dans son article, « Setting Height and Width on Images Is Important Again ». Nous avons passé beaucoup de temps à déterminer les valeurs correctes de largeur et de hauteur (plus les proportions) pour nos images dans chaque cas pour les ajouter à nouveau au code HTML. En conséquence, il n'y a plus de changement de mise en page pour les images car le navigateur obtient les informations tôt.

Le cas du mystérieux score CLS

Après avoir supprimé bon nombre des gros problèmes CLS près du haut de la page, nous avons heurté un barrage routier. Parfois (pas toujours) en regardant Page Speed ​​ou Lighthouse, nous avons obtenu un score CLS supérieur à 0,3, mais jamais dans l'onglet "Performance". Le générateur de gif de décalage de mise en page l'affichait parfois, mais il semblait que tout le conteneur de la page se déplaçait. L'en-tête sur mobile augmentait de 2 pixels de hauteur en raison des éléments qu'il contenait. Étant donné que l'en-tête est de toute façon une hauteur fixe sur mobile, nous avons opté pour le correctif simple et lui avons ajouté une hauteur explicite – boîtier fermé. Mais cela nous a coûté beaucoup de nerfs, et cela montre que l'outillage ici est encore très imprécis.

Layout Shift of Doom - cela a pris beaucoup de temps à comprendre
Layout Shift of Doom – cela a pris beaucoup de temps se rendre compte. ( Grand aperçu)
Cela ne fonctionne pas – Refaites-le !

Comme nous le savons tous, les scores mobiles sont beaucoup plus sévères pour la vitesse de page que pour le bureau, et un domaine où ils étaient particulièrement mauvais pour nous était sur les pages de produits. Le score CLS était fulgurant et la page présentait également des problèmes de performances (plusieurs carrousels, onglets et éléments non mis en cache le feront). Pour aggraver les choses, la mise en page de la page signifiait que certaines informations étaient mélangées ou ajoutées deux fois.

Sur le bureau, nous avons essentiellement deux colonnes pour le contenu :

  • Colonne A : la carrousel de photos de produits, parfois suivis de citations de blogueurs, suivis d'une mise en page à onglets avec des informations sur le produit.
  • Colonne B : le nom du produit, le prix, la description et le bouton « ajouter au panier ».
  • Ligne C : Le carrousel de produits de produits similaires.

Sur mobile, cependant, le carrousel de photos de produits devait apparaître en premier, puis la colonne B, puis la mise en page à onglets de la colonne A. En raison de Ceci, certaines informations étaient dupliquées dans le HTML, étant contrôlées par display: noneet l'ordre était basculé avec la propriété flex: order. Cela fonctionne certainement, mais ce n'est pas bon pour les scores CLS, car tout doit être réorganisé.

Les zones de page visualisées sur ordinateur et mobile pour montrer le problème principal.
Les zones de page visualisées sur ordinateur et mobile pour montrer le problème central. ( Grand aperçu)

J'ai opté pour une expérience simple dans CodePen : pourrais-je obtenir la même disposition de base des boîtes sur le bureau et sur le mobile en repensant le HTML et en utilisant display : grid au lieu de flexbox, et cela me permettrait-il simplement de réorganiser les zones de la grille selon les besoins ? Pour faire court, cela a fonctionné, et cela a résolu CLS, et cela a l'avantage supplémentaire que le nom du produit apparaît maintenant beaucoup plus tôt dans le HTML qu'auparavant – une victoire supplémentaire pour le référencement !

Voir le stylo [Jewellerybox Case Study (Example #2)](https ://codepen.io/smashingmag/pen/OJpzyLg) par Pfenya.

Voir l'étude de cas Pen Jewellerybox (exemple #2) par Pfenya .

Le mot « carrousel » est déjà revenu plusieurs fois – et pour cause. Non seulement avons-nous changé la bibliothèque de carrousel que nous utilisons (et modifié le comportement de chargement des images qu'elle contient), nous avons également dû nous en occuper pour CLS car nous avons plusieurs pages sur lesquelles le carrousel est au-dessus du pli et, par conséquent, pourrait avoir un impact important sur les scores de vitesse.

Nous avons commencé par charger le carrousel plus tard pour diminuer le temps d'interactivitémais cela a causé un retard visible jusqu'à ce que JavaScript se déclenche et que les diapositives se déplacent de être au-dessous de l'autre à être dans une rangée. Nous avons essayé de nombreuses façons d'écrire le CSS pour éviter que cela ne se produise et pour tout garder sur une seule ligne, y compris en masquant tout le carrousel jusqu'à ce qu'il ait fini de se charger. Rien ne nous a donné le genre de solution que nous aurions aimé voir lors de la visite d'un magasin en tant qu'utilisateur.

Désolé pour cette courte diatribe, mais vraiment, les carrousels de produits et de catégories sont la tempête parfaite d'éléments flexibles dans un magasin réactif : les images peuvent ne pas avoir une hauteur universelle, les noms de produits peuvent s'étendre sur plusieurs lignes et vous pouvez avoir ou non des étiquettes. En gros, cela se résume à ceci : aucune hauteur fixe pour la rangée n'est possible, et vous ne connaissez pas non plus vraiment la largeur. Fun times.

En fin de compte, nous avons décidé de régler toutes les diapositives (à l'exception de la première) sur visibilité : masquée jusqu'à ce que le carrousel ait fini de se charger, auquel cas nous ajoutez une classe au carrousel pour que toutes les diapositives soient à nouveau visibles. Cela résout le problème de la prise de hauteur supplémentaire au début. De plus, nous avons initialement défini flex-shrink: 0 et flex-base: 340px pour les diapositives dans une flexbox non enveloppante. Cela les fait être sur une seule ligne et donne une largeur initiale approximative pour les diapositives. Une fois ce casse-tête résolu – et oui, c'était aussi casse-tête que cela en a l'air – nous avons ajouté quelques correctifs pour laisser de la place aux points et aux flèches. Avec cela en place, il n'y a presque plus de CLS pour les carrousels !

Voir le stylo [Jewellerybox Case Study (Example #3)](https://codepen.io/smashingmag/pen/vYxpNEK) de Pfenya.[19659043]Voir le Pen Jewellerybox Case Study (Example #3) par Pfenya.

Hindsight Is 2020

Au final, ce sont beaucoup de petits changements sur plusieurs mois qui ont amélioré nos scores, et nous n'en avons pas fini. Nous avons principalement travaillé avec deux personnes sur les améliorations du front-end, tandis que le reste de l'équipe s'est concentré sur l'amélioration du back-end. Bien que cela soit probablement un peu plus lent de cette façon, cela garantissait qu'il n'y avait pas de chevauchement et que les différences de scores pouvaient être clairement attribuées. Certaines ressources qui ont beaucoup aidé étaient les excellents articles ici sur Smashing Magazine sur les propres améliorations du magazine.

Un score parfait de 100 sur le bureau pour la page d'accueil. Certaines sous-pages ont des scores similaires.
Un score parfait de 100 sur le bureau pour la page d'accueil. Certaines sous-pages ont des scores similaires. ( Grand aperçu)

À un moment donné, les choses que vous devriez essayer deviennent non évidentes parce que vous ne pensez pas qu'elles devraient faire une énorme différence, mais parfois après vous vous rendez compte qu'elles le font. More than that, what this project taught us again is how important it is to have performance and the metrics for it in mind from the very beginningfrom envisioning the design and coding the prototype to the implementation in the templates. Small things neglected early on can add up to huge mountains you have to climb later on to undo.

Largest contentful paint and first input delay over time — slow and steady wins the race!
Largest contentful paint and first input delay over time — slow and steady wins the race! (Large preview)

Here are some of the key aspects we learned:

  • Optimizing JavaScript is not as effective as loading it on demand;
  • Optimizing CSS seems to gain more points than optimizing JavaScript;
  • Write CSS classes with CLS and extraction of critical CSS in mind;
  • The tools for finding CLS problems aren’t perfect yet. Think outside the box and check several tools;
  • Evaluate each third-party service that you integrate for file size and performance timing. If possible, push back on integration of anything that would slow everything down;
  • Retest your page regularly for CrUX changes (and especially CLS);
  • Regularly check whether all of your legacy support entries are still needed.
We made good progress on “Core Web Vitals”.
We made good progress on “Core Web Vitals”. (Large preview)

We still have things on our list of improvements to make:

  • We still have a lot of unused CSS in the main file that could be removed;
  • We’d like to remove jQuery completely. This will mean rewriting parts of our code, especially in the checkout area;
  • More experiments need to be conducted on how to include the external sliders;
  • Our mobile point scores could be better. Further work will be needed for mobile especially;
  • Responsive images need to be added for all product images;
  • We’ll check the content pages specifically for improvements they may need, especially around CLS;
  • Elements using Bootstrap’s collapse plugin will be replaced with the native HTML details tag;
  • The DOM size needs to be reduced;
  • We will be integrating a third-party service for faster and better search results. This will come with a large JavaScript dependency that we will need to integrate;
  • We’ll work on improving accessibility both by looking at automated tools and by running some tests with screen readers and keyboard navigation ourselves.

Further Resources

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




Source link