Dans le monde très concurrentiel des services Internet, Google cherche constamment des moyens d'accélérer la diffusion de contenus à ses centaines de millions d'utilisateurs. Lors de la conférence O'Reilly Velocity qui s'est tenue la semaine dernière à New York (14-16 octobre), deux ingénieurs de Google ont livré certaines de leurs astuces et de leurs recherches pour accélérer la livraison de pages web et d'applications. Le genre d'informations très utiles à tout développeur qui cherche à rendre ses produits plus réactifs. Colt McAnlis, développeur chez Google et expert dans les questions de performances, a abordé l'un des problèmes les plus épineux auxquels sont confrontés les développeurs web mobiles d'aujourd'hui : les performances de JavaScript.
Les applications JavaScript basées sur le web peuvent souffrir de problèmes de performances, en particulier sur les clients mobiles, parce que les moteurs d'analyse JavaScript utilisent un récupérateur de mémoire ou Garbage Collector (GC) pour gérer la mémoire. « Vous ne devriez pas compter sur ce type d'outils », a déclaré Colt McAnlis aux développeurs présents à la conférence. Le Garbage Collector permet aux programmeurs de restituer automatiquement au système d'exploitation la mémoire dont un programme n'a plus besoin. L'écriture de code pour gérer la mémoire de langages de bas niveau comme le C et le C++ est un processus laborieux et de toutes les façons ces langages ne sont pas supportés nativement par les navigateurs. Le problème, avec de nombreuses applications JavaScript web, c'est que les moteurs JavaScript lancent leurs routines de récupération de mémoire à des intervalles aléatoires semble-t-il, ce qui provoque un ralentissement momentané des applications. Le débit d'images d'une application vidéo peut diminuer. Ou encore le temps qu'il faut à une application pour exécuter une opération peut passer à 20 millisecondes, contre 3 à 5 millisecondes normalement.
Convertir le code en JavaScript
« Globalement, pour que le GC travaille sans être remarqué par l'utilisateur, la mémoire système doit être six fois plus grande que la quantité de mémoire utilisée », a déclaré le développeur de Google, se référant à une étude bien connue. C'est une exigence de taille pour les terminaux mobiles compte tenu de la mémoire limitée dont ils disposent et le nombre d'applications gourmandes en mémoire qui tournent sur ces appareils. Ajouter à cela, l'utilisation croissante des « clôtures » ou « closures », une technique de programmation qui étend la disponibilité des variables définies localement. La bibliothèque JavaScript jQuery, par exemple, largement utilisée, s'appuie sur les clôtures et par conséquent, ajoute beaucoup d'éléments incontrôlables dans l'allocation de mémoire. « Les closures me font peur, tant ils peuvent être imprévisibles en terme de quantité de mémoire qu'ils peuvent consommer», a souligné Colt McAnlis.
Pour améliorer les performances, et mieux gérer la mémoire, les développeurs doivent adopter une approche similaire à celle de la bibliothèque middleware Emscripten, utilisée pour développer des jeux web très performants en HTML5. Celle-ci convertit le code écrit en C ou C++ en JavaScript, ce qui lui permet de gérer la mémoire au sein de l'application elle-même. Un programme basé sur ce logiciel va pré- allouer le bloc mémoire du système. Le programmeur, décide à quel moment la mémoire n'est plus nécessaire, et Emscripten restitue cette mémoire inutilisée au pool de mémoire disponible en interne. Le moteur JavaScript ne procède à aucune récupération de la mémoire sur le programme et n'affecte pas ses performances. D'une manière générale, les programmes écrits avec cette technique tournent deux à quatre fois plus vite que les programmes JavaScript typiques et ne souffrent pas des baisses de performances occasionnelles que provoque le travail du Garbage Collector », a expliqué le développeur.
Des astuces permettant d'anticiper
Dans une autre présentation, Steve Shoulders, également spécialisé dans la performance du web chez Google, a exposé d'autres techniques de navigation qui permettent de rechercher les pages web avant même qu'elles ne soient demandées par l'utilisateur. Comme l'a expliqué l'ingénieur, le navigateur doit être capable d'anticiper la page suivante que l'utilisateur pourrait vouloir voir, avant même que celui-ci ne demande la page. « Vous ne savez pas où le visiteur voudra aller, mais il est possible de collecter quelques indices sur ses intentions » par rapport à ses demandes », a précisé Steve Shoulders, avant de livrer plusieurs techniques permettant d'exploiter l'idée.
Les développeurs peuvent ajouter les balises HTML « dns-prefetch », « pre-fetch » et « pre-render » aux liens hypertextes d'une page. Une fois qu'une page est chargée, ces étiquettes peuvent indiquer au navigateur de récupérer une partie du contenu des pages qui sont liées à cette page d'origine, avant même que l'utilisateur n'en fasse la demande. La balise « dns-prefetch » indique au navigateur de rechercher le nom de domaine du lien de la page web. Le tag « pre-fetch » indique au navigateur de charger toute la page, et le tag « pre-render» demande au navigateur de construire la totalité de la page, comme s'il l'affichait dans un onglet caché. Ces trois balises, quand elles sont ajoutées, peuvent permettre de raccourcir le délai entre la demande d'une page web et son affichage. L'ingénieur recommande aux développeurs d'utiliser ces étiquettes à bon escient, car elles peuvent assécher la bande passante et le processeur. Mais dans de nombreuses situations, par exemple dans une page de connexion ou de résultats de recherche, la probabilité que l'utilisateur clique sur un des liens figurant sur la page est assez forte.
La prise en charge de ces balises par les navigateurs est variable, mais la plupart des éditeurs semblent l'ajouter dans leurs mises à jour. Les navigateurs comportent eux-mêmes un certain nombre de processus pour accélérer la livraison de page, comme la résolution anticipée de DNS et la préconnexion TCP. La résolution anticipée de DNS permet au navigateur d'anticiper le nom de domaine du site qui sera consulté. Pour cela, il regarde les lettres que l'utilisateur commence à taper dans la barre de navigation. Il peut même aller chercher systématiquement les adresses IP des sites les plus visités par l'utilisateur. La préconnexion TCP anticipe sur l'action de l'utilisateur par des moyens similaires. Il « active en amont » les connexions à certains sites, en ouvrant les ports et en préparant le réglage de tous les protocoles au cas où », a déclaré Steve Shoulders.