• Extensions

Magento 2 : Comment optimiser le chargement des fichiers JavaScripts

anthony_360f3c3132
Anthony Grutter, Chief Technical Officer - Co-fondateur
Le 8 octobre 2020
visuel_blog_2_1ec69f3b6d
  • ecommerce
  • performance web
  • Advanced JS

Lecture :5 minutes

La performance web est un point d’attention important dans l’e-commerce.

Elle influence votre positionnement en référencement naturel, votre coût-par-clic pour les annonces payantes mais aussi l’expérience client et donc votre taux de conversion.

Beaucoup d’aspects entrent en jeu pour améliorer les temps de réponse et Advanced JS Bundling est un concept qui améliore le chargement des fichiers JavaScripts.

 

 

 

 

Le JavaScript sur Magento 2

Avant de rentrer dans le détail de la solution apportée, voici un rappel de ce qui existe sur Magento 2.

 

RequireJs : gestion asynchrone du chargement

RequireJS est une librairie JavaScript permettant de gérer le chargement des fichiers JavaScript de manière asynchrone. Seuls les fichiers nécessaires, déclarés dans les dépendances de chaque bout de code sont chargés.

 

<script>   require.config({             deps: [                 'jquery',                 'mage/translate',                 'jquery/jquery-storageapi'             ], </script>

 

Minification : réduction du poids de la page

Les fichiers statiques JS de Magento peuvent être minifiés lors du déploiement. Les commentaires et espaces seront supprimés du code afin de réduire le poids de la page.

<script  type="text/javascript"  src=".../merged/526464e25b61833c4c2474dff007d8e3.min.js"></script>

 

Merge : réduire le nombre de ressources chargées

Afin de limiter les ressources chargées dans leur nombre, l’option de fusion permet de rassembler les fichiers d’un même type dans un seul et même fichier. Les fichiers chargés par RequireJS ne sont pas concernés par ce merge, car ils sont chargés plus tard dans le flux de chargement, en fonction des besoins de la page.

<script  type="text/javascript"  src=".../merged/526464e25b61833c4c2474dff007d8e3.min.js"></script>

 

Bundling JS : réduire le nombre d’appels du serveur

Les fichiers nécessaires par RequireJS sont regroupés et préchargés via des fichiers bundlesX.js. Lorsque la page en a besoin, ils sont déjà chargés en cache et plus aucun téléchargement n’est alors nécessaire.

La suite de l'exécution de la page est donc plus rapide, car on ne patiente plus pour chaque petit téléchargement de dépendances, tributaire de la qualité de votre connexion.

<script  type="text/javascript"  src=".../fr_FR/js/bundle/bundle0.min.js"></script>

<script  type="text/javascript"  src="... /fr_FR/js/bundle/bundle1.min.js"></script>

 

La problématique du bundling JS

Une performance améliorée avec le Bundling JS ?

Bien que l’option de Bundling JS puisse s’avérer intéressante à première vue, l’utiliser telle quelle aura plutôt tendance à dégrader la performance de votre site si vous n’y prêtez pas attention.

Le point faible du Bundling JS par Magento est que celui-ci génère des fichiers bundles qui contiennent l’intégralité des fichiers et modules JavaScript que l’on retrouve dans pub/static/frontend/MonTheme. C’est à dire de tous les modules Magento activés et du thème, que ce soit utile ou non. On retrouve dans ces fichiers bundles.js des JS qui ne concernent que le Checkout, ou pire encore, des JS qui ne concernent que l’admin ou même aucune page.

Nous retrouvons sur cet exemple la librairie TinyMCE (pour l’éditeur wysiwyg) pré-chargée sur notre homepage. En multipliant ces insertions inutiles, on augmente le poids de la page. Le gain obtenu en réduisant le nombre d’appels sera alors vite effacé par la surcharge de bytes téléchargés.

 

Comparatif des avantages avec et sans le Bundling JS natif Magento

Sans Bundling JS 

  • Réduit au minimum les bytes transférés, seules les ressources nécessaires sont téléchargées

  • Ne retarde pas le premier rendu de la page

  • Mauvaise utilisation du réseau dû à un chargement en cascade des ressources. Les connexions lentes seront très impactées car il faut multiplier les connexions au serveur
    (environ 200 fichiers JS séparés = 200 connexions serveurs)

 

Avec Bundling JS natif Magento

  • Réduit le nombre de requêtes HTTP. Économie sur le temps de connexion au serveur

  • Augmente le nombre de bytes téléchargés et interprétés (chargement inutile)

  • Retarde le premier rendu le temps du téléchargement des JS bundles

  

Configuration JS Bundling avancée : la méthode officielle

bundles-js-blackbird-magento2

 

Le constat est simple : réduire le nombre d’appels est une bonne piste d’optimisation, mais pas au détriment du poids de la page, car l’expérience sera au final détériorée.

La documentation officielle de Magento traite ce sujet : https://devdocs.magento.com/guides/v2.4/performance-best-practices/advanced-js-bundling.html

Elle explique comment procéder pour regrouper les fichiers par type de page.
L’objectif est de créer des bundles généraux chargés pour toutes les pages et d’autres spécifiques (checkout, fiche produit, etc.)

Le procédé est long et source d’erreurs, car il faut générer du JSON pour déclarer le tout en fonction d’appels que l’on voit passer sur son navigateur. Une rapide lecture de la documentation vous montrera à quel point cela est fastidieux : à base de JSON à fusionner à la main, de commandes sed, d’installation de librairies JS pour simuler les navigations et enregistrer les ressources qui transitent… Sans compter la maintenabilité du fichier généré, cette lourdeur est très rebutante.

Bien que des outils soient proposés par la communauté pour simplifier le process (https://github.com/magento/baler), le principe reste assez proche de ce que Magento explique dans sa documentation et nous semble insuffisant. Nous avons donc développé l’extension Advanced JS Bundling afin de rendre cette tâche plus rapide et plus facile à maintenir.

 

La méthode proposée par Blackbird

Afin de dispatcher facilement les modules par section du site, de simples champs de configuration sont disponible dans le backoffice.

Il suffit de lister dans ces champs le nom du module ou du fichier que l’on souhaite retirer du bundle général et placer dans un autre bundle.

Il est également possible de lister des modules et fichiers que l’on ne souhaite plus du tout charger via les bundles. Ces fichiers continueront alors d’être chargés par RequireJS en cas de besoin uniquement.

 

 methode-par-Blackbird-bundle-js

 

 

Lors de la génération des fichiers bundles via la commande bin/magento setup:static-content:deploy de nouveaux fichiers seront générés (fonctionne uniquement en mode Production)

magento-2-bundle-js

Ces fichiers bundles spécifiques seront chargés uniquement sur les routes que vous spécifiez aussi dans la configuration.

Pour repérer facilement les fichiers qu’il faut exclure ou rendre bundle specific, vous pouvez :

  1. Observer les dossiers qui sont dans votre thème : pub/static/frontend/theme/fr_FR/
  2. Inspecter le contenu des fichiers bundles depuis l’onglet Network / Preview de Chrome afin d’avoir une vue plus détaillée et de choisir les fichiers les plus volumineux à cibler.

 

extension-bundle-js-magento-2

 

Des configurations par défaut sont fournies avec l’extension Advanced JS Bundling par Blackbird afin de faciliter sa mise en œuvre.

Si vous le pouvez, il reste toujours préférable de désactiver un module qui n’est nécessaire nul part sur le site (possible selon ses dépendances) : bin/magento module:disable Amazon_Login

Abonnez-vous au blog pour ne rien louper