Le JavaScript a souvent un grand rôle à jouer dans la vitesse de chargement des sites. Nous faisons de plus en plus appel à des librairies telles que jQuery, Prototype ou Dojo. Le téléchargement de ces ressources prends du temps et bloque le chargement des autres éléments de la page. Dans la boucle que constitue l’Optimisation des Performances du Web, l’amélioration de l’Expérience Utilisateur (UX) fait partie de l’une des 4 étapes clés. C’est sur cette étape que nous allons jouer.
Avec et sans Javascript
WebPageTest est un outil comme beaucoup d’autres qui permet de tester la vitesse de chargement de votre site internet. Par contre, il a la particularité de pouvoir bloquer le chargement de certains fichiers :
Le résultat est sans appel. Non seulement la vitesse de chargement explose avec un ou plusieurs fichiers JavaScript mais également le poids de la page (les deux sont liés vous me direz). Selon les statistiques Alexa réalisées sur 100 pages, un site avec du JavaScript prend en moyenne 31% de plus de temps pour s’afficher.
Optimisation du Javascript : historique
Différentes optimisations se sont développées au fil des années. Elles ne sont plus adaptés aujourd’hui. Elles fonctionnent toujours mais de nouvelles techniques sont maintenant beaucoup plus efficaces. Néanmoins, voici un petit historique.
1995 : script dans les balises head
<head> <script src='a.js'></script> </head>
Caractéristiques :
- bloque les autres téléchargements pour certains navigateurs
- téléchargement séquentiel
- bloque l’affichage d’autres éléments de la page pendant le téléchargement, l’analyse et l’exécution
2007 : script avant la balise fermante body
<!-- code --> <script src='a.js'></script> </body>
Caractéristiques :
- ne bloque pas les autres téléchargements
- téléchargement séquentiel
- bloque l’affichage d’autres éléments pendant
le téléchargementl’analyse et l’exécution
2009 : chargement asynchrone
(function () { var se = document.createElement('script'); se.src = 'a.js'; se.type = 'text/javascript'; se.async = true; document.getElementByTagName('head')[0].appendChild(se); })();
Caractéristiques :
- ne bloque pas les autres téléchargements
- téléchargement en parallèle
- bloque l’affichage d’autres éléments pendant l’analyse et l’exécution
PS : c’est un code qui se met à la fin du document HTML et qui a pour effet de lancer le chargement du fichier JavaScript une fois seulement la page chargée
2010 : chargement asynchrone et exécution à la demande
var se = new Image(); se.onload = registerScript; se.src = 'a.js';
Caractéristiques :
- ne bloque pas les autres téléchargements
- téléchargement en parallèle
- ne bloque pas l’affiche des autres éléments avant que ça soit demandé
- sépare le téléchargement du script de l’analyse et de l’exécution
Performances JavaScript en 2012
ControlJS va encore plus loin. Il est toutefois basé sur certaines mêmes techniques d’optimisations à savoir chargement asynchrone et exécution différée des scripts. Comme dit précédemment, pendant que le navigateur interprète le JavaScript puis l’exécute, il ne peut pas faire grand chose de plus. Ce qui veut dire que tous les éléments de l’interface utilisateur ne fonctionnent pas, que le navigateur ne télécharge pas d’autres fichiers et que l’affichage de la page s’arrête. D’après une autre étude Alexa, 29% des scripts JavaScript sont appelé avant le chargement complet de la page. Le principe de ControlJS est de télécharger le script en parallèle au chargement de la page et de l’exécuter uniquement lorsque le navigateur en a besoin.
Implémentation
La première étape consiste simplement à ajouter ControlJS dans le head :
var cjsscript = document.createElement('script'); cjsscript.src = "control.js"; var cjssib = document.getElementsByTagName('script')[0]; cjssib.parentNode.insertBefore(cjsscript, cjssib);
Puis modifiez les appels de vos scripts externes
<script type="text/javascript" src="jquery.js"><script>
par
<script type="text/cjs" data-cjssrc="jquery.js"><script>
Modifiez également les appels de vos scripts développés dans la page elle-même (inline)
<script type="text/javascript"> var nom = getNom(); </script>
par
<script type="text/cjs"> var nom = getNom(); </script>
Le chargement des pages n’est plus bloqué car nous avons modifiés l’attribut type par quelque chose qu’il ne connait pas. Cela permet à ControlJS de prendre le contrôle dessus d’une manière plus performante.
Test sans control.js
Test avec control.js
Télécharges maintenant, exécutes plus tard
La deuxième solution avec ControlJS est de charger les scripts dans un premier temps, et d’y faire appel par la suite, quand on en a besoin. L’avantage est que la page se charge très vite. Par contre, comme tout le code est exécuté lorsque l’on fait l’action, la page aura un temps de chargement la première fois que le script sera appelé. Presque comme avant, les scripts sont appelés :
<script data-cjsexec=false type="text/cjs" data-cjssrc="jquery.min.js"></script> <script data-cjsexec=false type="text/cjs" data-cjssrc="fg.menu.js"></script>
Puis il est appelé lorsqu’on en a besoin. Ici, lorsque l’on clique sur un bouton :
examplesbtn.onclick = function () { CJS.execScript("jquery.min.js"); CJS.execScript("fg.menu.js", createExamplesMenu); };
Pour les personnes qui ne veulent pas trop chercher, la solution du chargement asynchrone simple est la plus facile à mettre en place.
3 Comments on “Javascript : accélérer le chargement d’un site internet”
Mais ControlJS date de 2010…… et ne contient aucune nouveautés depuis
Et pour le script de Google analytics ? On utilise la même méthode ?
Le code de Google Analytics est relativement bien optimisé mais il y a certaines erreurs et gains de performance qui peuvent être mis en place. Voici un code Analytics optimisé :