Méthodologie et Quick Win des applications JavaScript
Au cours de l’événement Performance.Now() 2018, nous avons pu assister à de nombreuses conférences concernant la performance des applications Web. La première à été réalisée par Steve Souders qui nous a fourni une méthodologie simple pour réaliser un ensemble de Quick Win dans des applications web utilisant JavaScript.
JavaScript est une des technologies les plus utilisées dans le domaine des applications web mais aussi une des plus consommatrices de temps réseau et processeur. Elle possède pourtant de nombreuses options permettant de réduire son impact sur les performances.
1. Préchargement et exécution asynchrone / différé
Le chargement classique de script JavaScript par défaut dans un navigateur se réalise un script après l’autre. En fonction de la quantité et de la taille des scripts, ce processus peut prendre beaucoup de temps et a un impact fort sur le ressenti utilisateur le premier rendu visuel n’ayant lieu qu’après l’exécution du dernier script.
Chargement classique JavaScript
Afin d’améliorer ce fonctionnement, plusieurs mécanismes peuvent être mis en place.
D’abord l’utilisation du Preloader. Il permet d’indiquer au navigateur les ressources dont nous aurons besoin peu après le chargement de la page. Les différents scripts peuvent ainsi être téléchargés parallèlement.
Chargement d’une page avec Preloader
On constate sur le graphique que les scripts sont maintenant chargés simultanément. Cette amélioration est aujourd’hui celle qui apporte la plus grande amélioration dans le temps de chargement d’une page.
Cependant, l’exécution des scripts (symbolisé par les barres vertes) n’est pas réalisée en fonction de la fin de leur téléchargement mais de leur ordre d’exécution (ordre d’apparition dans le fichier HTML). Dans le cas présenté, certains scripts téléchargés doivent attendre la fin du téléchargement et de l’exécution d’un autre script avant de pouvoir s’exécuter. De plus, tant que les scripts n’ont pas été exécutés, le parser HTML est bloqué et rien n’est affiché sur la page.
Afin de réduire ces impacts, deux attributs peuvent être utilisés :
• Async
• Defer
Ces deux méthodes ne bloquent pas le Parser HTML pendant le téléchargement des scripts et permettent donc d’obtenir un premier affichage plus rapide dans le navigateur.
Chargement d’une page avec Preload et Async
Dans l’exemple ci-dessus, on constate qu’avec l’attribut Async, les scripts sont exécutés dès leurs téléchargements, n’arrêtant le parser HTML que pendant la durée de leurs exécutions.
Malgré le gain de rapidité, ce comportement doit être utilisé avec précaution. Il ne permet pas conserver l’ordre d’exécution et, par exemple, ne peut pas être appliqué à des scripts ayant besoin du résultat d’autres scripts.
L’attribut Defer réalise le téléchargement des scripts pendant l’affichage du contenu HTML de la page puis les exécute. Ainsi, l’ordre d’exécution est conservé et le parser HTML n’est jamais bloqué.
Nous pouvons tout de même constater (en rouge sur le graphique) des temps de chargement parfois importants sur l’exécution des scripts.
2. Utilisation du temps CPU
Il est possible de constater, grâce à des données obtenues via https://www.httparchive.org, que le temps d’exécution des scripts JS utilise une quantité importante de temps CPU. Pour réduire ces effets, deux actions peuvent être envisagés :
• La réduction du nombre de scripts JS au minimum nécessaire.
• Faire attention à l’utilisation de fonctions telle que EvaluateScript et FunctionCall qui sont les plus grandes consommatrices de temps CPU.
3. Third party scripts
Un autre élément qui doit être maitrisé et quantifié est l’utilisation des Third Party scripts
En moyenne, leurs quantités dans les applications web a plus que doublé depuis 2011 et leurs tailles ont été multipliées par 5. Pour ces raisons, il est important d’inventorier ces scripts, de n’utiliser que le nécessaire et de mesurer l’impact de chacun d’entre eux sur les performances des applications.
4. Compression des scripts
Pour continuer, il faut également considérer l’importance de la compression des scripts.
Sur ce graphique, on peut constater la quantité de données économisées par rapport à la taille du fichier de base en utilisant la compression GZIP. Cela permet d’augmenter la rapidité des transferts en réduisant la quantité de données via une option à activer directement sur les serveurs web.
5. Revue de code des scripts
Enfin, une dernière action est conseillée mais est plus complexe à mettre en œuvre. Lors de l’utilisation de scripts JavaScript, il est possible qu’une grande partie du contenu du script ne soit en réalité pas utilisé.
Sur l’image ci-dessus, on peut voir que le site n’utilise pas 79,4 % du script foundation.min.js. Dans ce cas, une revue du code peut être effectué afin de vérifier si ce contenu n’est pas utilisé dans d’autres pages du site et, s’il ne l’est pas, alléger le script au minimum nécessaire.
6. Conclusion
Afin de réduire l’impact de javascript sur le ressenti des utilisateurs d’une application web, nous pouvons :
• Utiliser l’attribut Payload
• Utiliser les attributs Async et/ou Defer
• Tenter de réduire l’impact sur le processeur (réduction du nombre de scripts, non utilisation de fonction consommatrice en temps CPU)
• Quantifier l’impact des 3rd party scripts
• Compresser les scripts JavaScript
• Réaliser des revues du code réellement utilisé dans les scripts
Même si ces améliorations peuvent paraître minime (certaines sont de l’ordre de la centaines de millisecondes) il est important de reporter leur impact sur la quantité de connexion que peut recevoir une application. Nous avons pu voir au cours de conférences que ces améliorations pouvaient avoir des impacts forts sur le chiffre d’affaires d’une entreprises. Un exemples nous à été donné au cours d’une autre conférence :
Walmart saw up to a 2% increase in conversions for every 1 second of improvement in load time. Every 100ms improvment also resulted in up to a 1% increase in revenue.
Sources :
Conference :
https://www.youtube.com/watch?v=RwSlubTBnew&list=PLjnstNlepBvMnKuNFvWeQWzlRp8Cbiw0X&index=2
Preload
https://developer.mozilla.org/fr/docs/Web/HTML/Précharger_du_contenu
https://w3c.github.io/preload/#x2.link-type-preload
Async et Defer :
https://www.alsacreations.com/astuce/lire/1562-script-attribut-async-defer.html
CPU et third party scripts:
https://www.httparchive.org
Compression :
https://developer.mozilla.org/fr/docs/Glossaire/GZip_compression
https://www.alsacreations.com/article/lire/914-compression-pages-html-css-gzip-deflate.html