Améliorer les performances d'une boutique en ligne (étude de cas)
Publié: 2022-03-10Chaque développeur front-end poursuit le même Saint Graal de la performance : des 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 de vos utilisateurs et la façon dont le site Web "se sent" lorsque vous l'utilisez ne doivent pas être ignorées, même si cela vous coûte un point ou deux en vitesse de page (sinon, nous aurions tous juste une barre de recherche et sans style texte).
Je travaille dans une petite agence numérique et mon équipe travaille principalement sur de grands sites Web et magasins d'entreprise. un effet secondaire malheureux de la taille et de la structure du projet dans les entreprises.
Travailler avec jewellerybox sur sa boutique en ligne a été 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 intégré dans les modèles - et pour une fois, nous avons également eu un client obsédé par les performances du site Web.
Pour le lancement, nous nous sommes principalement concentrés sur la mise en place du nouveau design, mais une fois la relance du site Web mise en ligne, nous avons commencé à concentrer notre attention sur la transformation des scores rouges et orange en verts. Ce fut un voyage de plusieurs mois rempli 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 souligner une partie du travail que nous avons effectué et comment nous avons pu atteindre notre vitesse.
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 boutiques en ligne sont différentes de nombreux autres sites Web (si vous le savez déjà, nous vous rencontrerons dans la section suivante). Quand on parle d'un site e-commerce, les principales pages que vous aurez sont :
- la page d'accueil (et les pages « contenu »),
- pages de catégories et de recherche,
- fiches produits,
- le panier et la caisse (évidemment).
Pour cet article, nous nous concentrerons 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 supplémentaire et de logique back-end 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.
C'est évidemment en plus de la validation des champs des formulaires qu'il vous faudra 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.
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 fondamentalement partout et domineront votre conception. De plus, vous voudrez montrer de nombreux produits pour inciter les gens à acheter chez vous - c'est donc un carrousel. Mais attendez! Les gens cliquent-ils sur les produits qu'il contient ? Nous pouvons le savoir en mettant un 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 la vitesse que vous ajoutez à la page pour présenter plus de produits dans l'espoir d'attirer plus de 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 chat pour entrer en contact avec le support 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 JavaScript commencent à s'accumuler, même si vous avez commencé avec les meilleures intentions de le garder maigre.
Et bien que vous puissiez généralement mettre en cache la page complète d'un article, il n'en va pas de même pour de nombreuses pages et éléments de boutique. Certains 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, ils ne doivent jamais être mis en cache. De plus, si vous avez des biens physiques, vous avez affaire à un inventaire en direct : pendant la ruée vers 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 pendant le rendu côté serveur.
Mais même dans les phases de planification, des pièges vous attendent. Dans une conception - et souvent aussi dans 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 les produits 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 d'eux.
Par conséquent, il est utile que les concepteurs ou les personnes qui réalisent le test du prototype avec des chaînes très courtes et très longues pour s'assurer que la conception convient toujours. De même, avoir des informations apparaissant 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 d'une catégorie de produits. page. Il est difficile de les garder synchronisés - 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 devrait être intégrée dès le stade du prototype est l'accessibilité. Plusieurs outils là-bas peuvent vous aider avec certaines des bases, d'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). 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 à nouveau les performances d'une boutique ? La réponse évidente est que vous voulez que les gens achètent chez vous . Il existe plusieurs façons d'affecter cela, 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 le résultat net.
Choses pratiques que nous avons faites
Certains goulots d'étranglement de performance sont faciles à identifier, mais une amélioration complète est un voyage plus long, avec de nombreux rebondissements. Nous avons commencé par toutes les choses habituelles, telles que revérifier la mise en cache des ressources, voir ce que nous pourrions prérécupérer ou charger de manière asynchrone, nous assurer que nous utilisons HTTP/2 et TLSv1.3. Beaucoup d'entre eux sont couverts dans l'aperçu utile de CSS-Tricks, et Smashing Magazine propose une excellente liste de contrôle PDF.
Tout d'abord : choses chargées sur toutes les pages
Parlons des ressources, et pas seulement de CSS ou de 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 communs étaient les suivants.
Chargement de l'icône
Comme sur de nombreux sites Web, nous utilisons plusieurs icônes dans notre conception. Le prototype était livré avec des icônes personnalisées qui étaient des symboles SVG intégrés. Celles-ci étaient stockées 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 svg
lié dans le corps du HTML. Cela a l'avantage de les rendre directement disponibles pour le navigateur lors du chargement du document, mais le navigateur ne peut évidemment 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 ne devra être interprété. Nous prenons également en charge l'utilisation de Font Awesome sur la page (que nous chargeons via JavaScript), mais nous le chargeons à la demande (en ajoutant un petit script qui vérifie les balises <i>
, puis en chargeant le JavaScript Font Awesome pour obtenir n'importe quel SVG icônes qu'il trouve). Parce que nous nous en tenons à nos propres icônes au-dessus du pli, nous pouvons exécuter le script entier après le chargement du DOM.
Nous utilisons également des emoji à certains endroits pour les icônes colorées, quelque chose auquel aucun d'entre nous n'a vraiment pensé mais 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 (la seule mise en garde étant les différentes conceptions sur différents systèmes d'exploitation).
Chargement de la police
Comme sur tant d'autres sites Web, nous utilisons des polices Web pour nos besoins en typographie. La conception nécessite deux polices dans le corps ( Josefin Sans en deux poids), 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 la manière d'éviter les changements de mise en page avec le chargement des polices, nous avons expérimenté la suppression de la version en gras et l'utilisation de la version normale.
Lors de nos tests, la différence visuelle était si faible qu'aucun de nos testeurs n'a pu le dire sans voir les deux en même temps. Donc, nous avons laissé tomber 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 des é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 conserver le faux gras et d'utiliser -webkit-text-stroke: 0.3px
pour aider ces navigateurs particuliers. La différence par rapport à l'utilisation du poids de police séparé réel 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é, aficionados des polices).
De plus, plusieurs produits peuvent être personnalisés avec des gravures . Ces gravures peuvent être réalisées en 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.
Assistance héritée
Un jour, CSS-Tricks m'a surpris avec un article sur "Comment faire du 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 n'était peut-être plus nécessaire. Sur la base de l'article, nous avons limité nos listes de favicons et d'icônes tactiles aux versions recommandées.
De même, nous avons également converti une police que nous n'avions qu'en 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 repli). Et nous avons purgé les directives CSS qui ne sont plus nécessaires.
Chargement paresseux et à la demande
Plusieurs mesures 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 chute d'activité du réseau a beaucoup aidé ici, mais il en va de même pour la réflexion sur les flux d'utilisateurs. Par exemple, l'image agrandie du produit peut être chargée la première fois qu'un utilisateur interagit avec l'image du produit, et les images du 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 des ressources de prélecture.
Une chose que nous avons remarquée très tôt était le grand 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 le JavaScript était configuré pour se charger de manière asynchrone, Google l'incluait dans les mesures de temps d'interaction.
Nous n'avons pas été en mesure de déterminer complètement pourquoi c'était le cas, mais entre cela et la taille même de celui-ci, 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 également beaucoup plus petit. Pour l'améliorer davantage, nous ne chargeons initialement que l'icône du chat ; le reste est chargé lorsque vous cliquez pour l'ouvrir.
Le carrousel tiers invisible
Jewellerybox voulait essayer un service tiers qui utilise l'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 carrousels non personnalisés et peuvent également être mis en cache avec une clé de cache unique.
Il y a cependant un inconvénient : cela signifie que le rendu initial de la page côté serveur peut être plus lent à moins d'être 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 de rendre un espace réservé dans un premier temps.
Second Up : Optimiser JavaScript - Une bataille acharnée contre des ennemis externes
Le carrousel nous amène au deuxième grand domaine sur lequel nous nous sommes concentrés : JavaScript. Nous avons audité le JavaScript que nous avions, 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 si ce n'est qu'une fraction de votre code global - les gros gains résident dans les bibliothèques.
Optimiser des éléments dans les bibliothèques ou retirer des pièces dont vous n'avez pas besoin est, selon toute vraisemblance, une course folle. 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 avons examiné les bibliothèques que nous utilisons et ce pour quoi nous en avons besoin , et nous avons recherché pour chacune s'il existe une alternative plus petite ou plus rapide qui réponde tout aussi bien à nos besoins.
Dans plusieurs cas, il y en avait ! Par exemple, nous avons décidé de remplacer la bibliothèque de curseurs Slick par GliderJS, qui 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.
Comme nous utilisons Bootstrap 4, nous incluons toujours jQuery pour le projet, mais nous travaillons à tout remplacer par 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 tourne plus vite. 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 « 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 de 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, il était en fait plus rapide en raison de la 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 être valables pour l'autre.
Troisième place : Images - Formats, tailles et tout ce 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 Jewellerybox existe depuis près de 10 ans et de nombreux produits sont disponibles depuis la majeure partie de cette période. Par conséquent, les images de produits d'origine ne sont pas uniformes en termes de taille et de 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 signifierait beaucoup de travail de conversion à faire. Pour cette raison, nous utilisons actuellement une taille optimisée d'images de produits, mais nous n'avons pas d'images réactives pour celles-ci. Une mise à jour qui 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é universellement, il peut ralentir les images initialement visibles, plutôt que de les charger directement (ou du moins, c'est comme ça pour l'utilisateur). Pour cette raison, nous avons opté pour une combinaison de chargement direct des premiers et de chargement différé du reste, en utilisant une combinaison de chargement différé natif et d'un script.
Pour le logo du site Web, nous utilisons un fichier SVG, dont nous avons obtenu une version initiale du client. Le logo est une police complexe dans laquelle des parties des lettres manquent, comme elles le seraient dans une impression imparfaite faite à la main. Dans les grandes tailles, vous auriez besoin de montrer les détails, mais sur le site Web, nous ne l'utilisons jamais au-dessus de 150 par 30 pixels. Le fichier d'origine avait une taille de 192 Ko, pas énorme mais pas super petit non plus. Nous avons décidé de jouer avec le SVG et d'en réduire les détails, et nous nous sommes retrouvés avec une version décompressée de 40 Ko. Il n'y a aucune différence visuelle dans les tailles d'affichage que nous utilisons.
Dernier mais non des moindres : CSS
CSS critique
CSS figure énormément dans le rapport sur l'expérience utilisateur Chrome (CrUX) de Google et figure également en bonne place dans le rapport et les recommandations Google Page Speed Insights. L'une des premières choses que nous avons faites a été de définir des CSS critiques, que nous chargeons directement dans le HTML afin qu'ils soient disponibles pour le navigateur dès que possible - c'est votre arme principale pour lutter contre les changements de disposition 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 les noms de classe à 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 sur les 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 des CSS ne soit pas modifié par cela. Entre différentes personnes écrivant le code, quelqu'un ajoutant un remplacement plus tard dans le fichier et un outil automatique extrayant des éléments, cela peut devenir désordonné.
Dimensions explicites par rapport à CLS
Pour moi, CLS est quelque chose que Google a sorti de son chapeau, et maintenant nous devons tous y faire face 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 "Performance" dans les outils de développement et le générateur GIF de changement de disposition très utile pour voir quels éléments sont à l'origine du CLS. À partir de là, nous avons regardé 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 mobile pour éviter un changement de mise en page - mais d'autres fois, la lutte était réelle.
Conseil de pro : Parfois, un décalage n'est pas causé 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 à se poser est : Qu'est-ce qui pourrait faire bouger ce bloc ?
Parce qu'il y a tellement d'images sur la page, les faire se comporter correctement avec CLS nous a également demandé 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 rapports d'aspect) pour nos images dans chaque cas pour les ajouter à nouveau au HTML. Par conséquent, il n'y a plus de changement de mise en page pour les images car le navigateur obtient les informations plus tôt.
Le cas du mystérieux score CLS
Après avoir supprimé un grand nombre des gros problèmes CLS en haut de la page, nous nous sommes heurtés à un obstacle. 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 GIF Layout Shift l'a parfois montré, mais il semblait que tout le conteneur de page bougeait .
Avec la limitation du réseau et du processeur activée, nous l'avons enfin vu dans les captures d'écran ! L'en-tête sur mobile augmentait de 2 pixels en hauteur en raison des éléments qu'il contenait. Étant donné que l'en-tête a de toute façon une hauteur fixe sur mobile, nous avons opté pour le correctif simple et y avons ajouté une hauteur explicite - affaire close. Mais cela nous a coûté beaucoup de nerfs, et cela montre que l'outillage ici est encore très imprécis.
Cela ne fonctionne pas - Recommençons !
Comme nous le savons tous, les scores mobiles sont beaucoup plus sévères pour Page Speed que pour les ordinateurs de bureau, et un domaine où ils étaient particulièrement mauvais pour nous était sur les pages de produits. Le score CLS était à travers le toit, et la page avait également des problèmes de performances (plusieurs carrousels, onglets et éléments non cachables le feraient). 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 ordinateur, nous avons essentiellement deux colonnes pour le contenu :
- Colonne A : Le carrousel de photos de produits, parfois suivi de citations de blogueurs, suivi 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 ».
- Rangée C : Le carrousel de produits de produits similaires.
Sur mobile, cependant, le carrousel de photos de produits devait venir en premier, puis la colonne B, puis la mise en page à onglets de la colonne A. De ce fait, certaines informations étaient dupliquées dans le HTML, étant contrôlées par display: none
, et la commande était en cours commuté avec la propriété flex: order
. Cela fonctionne certainement, mais ce n'est pas bon pour les scores CLS car fondamentalement, tout doit être réorganisé.
J'ai décidé de faire une expérience simple dans CodePen : pourrais-je obtenir la même disposition de base des boîtes sur ordinateur et sur 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 mes besoins ? Pour faire court, cela a fonctionné et cela a résolu CLS, et il a l'avantage supplémentaire que le nom du produit apparaît maintenant beaucoup plus tôt dans le HTML qu'auparavant - une victoire SEO supplémentaire !
Pirater un carrousel pour CLS
Le mot "carrousel" est déjà revenu plusieurs fois - et avec raison. Non seulement nous avons changé la bibliothèque carrousel que nous utilisons (et modifié le comportement de chargement des images qu'elle contient), mais 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 réduire le temps d'interactivité , mais cela a causé un retard visible jusqu'à ce que le JavaScript se déclenche et que les diapositives passent de l'une au-dessous de l'autre à une seule 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 une boutique réactive : les images peuvent ne pas être d'une hauteur universelle, les noms de produits peuvent s'étendre sur plusieurs lignes et vous pouvez ou non avoir des étiquettes. En gros, cela se résume à ceci : aucune hauteur fixe pour la ligne n'est possible, et vous ne connaissez pas non plus vraiment la largeur. Des moments de plaisir.
Au final, nous avons décidé de définir toutes les diapositives (à l'exception de la première) sur visibility: hidden
jusqu'à ce que le carrousel ait fini de se charger, auquel cas nous ajoutons 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 boîte flexible sans habillage. Cela les place 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 autant un casse-tête que cela puisse paraître – 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 !
Le recul est de 20 ⁄ 20
Au final, ce sont pas mal de petits changements sur plusieurs mois qui ont amélioré nos scores, et nous n'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 ce 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 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 quelque temps après, vous vous rendez compte qu'elles le font. Plus que cela, ce projet nous a encore appris à quel point il est important d' avoir à l'esprit les performances et les mesures correspondantes dès le début , de la conception de la conception et du codage du prototype à la mise en œuvre dans les modèles. De petites choses négligées au début peuvent s'ajouter à d'énormes montagnes que vous devrez gravir plus tard pour les défaire.
Voici quelques-uns des aspects clés que nous avons appris :
- Optimiser JavaScript n'est pas aussi efficace que de le charger à la demande ;
- L'optimisation CSS semble gagner plus de points que l'optimisation de JavaScript ;
- Écrire des classes CSS avec CLS et extraire les CSS critiques à l'esprit ;
- Les outils pour trouver les problèmes CLS ne sont pas encore parfaits. Sortez des sentiers battus et vérifiez plusieurs outils ;
- Évaluez chaque service tiers que vous intégrez en fonction de la taille du fichier et de la durée des performances. Si possible, repoussez l'intégration de tout ce qui ralentirait tout ;
- Retestez régulièrement votre page pour les modifications CrUX (et en particulier CLS);
- Vérifiez régulièrement si toutes vos entrées de support héritées sont toujours nécessaires.
Nous avons encore des choses sur notre liste d'améliorations à apporter :
- Nous avons encore beaucoup de CSS inutilisés dans le fichier principal qui pourraient être supprimés ;
- Nous aimerions supprimer complètement jQuery. Cela impliquera de réécrire des parties de notre code, en particulier dans la zone de paiement ;
- Plus d'expériences doivent être menées sur la façon d'inclure les curseurs externes ;
- Nos scores de points mobiles pourraient être meilleurs. Des travaux supplémentaires seront nécessaires pour le mobile en particulier ;
- Des images réactives doivent être ajoutées pour toutes les images de produits ;
- Nous vérifierons spécifiquement les pages de contenu pour les améliorations dont elles pourraient avoir besoin, en particulier autour de CLS ;
- Les éléments utilisant le plugin d'effondrement de Bootstrap seront remplacés par la balise de
details
HTML native ; - La taille du DOM doit être réduite ;
- Nous intégrerons un service tiers pour des résultats de recherche plus rapides et de meilleure qualité. Cela viendra avec une grande dépendance JavaScript que nous devrons intégrer ;
- Nous travaillerons à améliorer l'accessibilité à la fois en examinant des outils automatisés et en exécutant nous-mêmes des tests avec des lecteurs d'écran et la navigation au clavier.
Autres ressources
- "Conseils et raccourcis de débogage DevTools (Chrome, Firefox, Edge)", Vitaly Friedman, Smashing Magazine
- "Certains articles de blog sur les performances que j'ai mis en signet et lus récemment", Chris Coyier, CSS-Tricks
- "Un guide détaillé pour mesurer les éléments vitaux du Web de base", Barry Pollard, Smashing Magazine
- "Du CSS sémantique à Tailwind : refactorisation de la base de code de l'interface utilisateur Netlify", Charlie Gerard et Leslie Cohn-Wein, Netlify
- "Outils d'audit CSS", Iris Lješnjanin, Smashing Magazine
- "Ce que vous pouvez faire avec CSS aujourd'hui", Andy Bell, Smashing Magazine
- "Comment améliorer les performances CSS", Milica Mihajlija, Calibre
- "L'écart d'inégalité des performances mobiles, 2021", Alex Russell
- "Optimiser au maximum le chargement des images pour le Web en 2021", Malte Ubl
- "L'élément humble
<img>
et les éléments vitaux du Web de base", Addy Osmani, Smashing Magazine