
-
JavaScript, les bonnes pratiques : optimiser vos scripts (2/2)
Le 2 décembre 2010 par Maxime dans Conception web.
Nous avons discuté dans un article précédant des différentes optimisations de base que l’on peut apporter facilement à ses scripts js. Attaquons maintenant des notions un peu plus techniques, en décortiquant les points sensibles du JavaScript en termes de performance.On pourra alors déceler les erreurs à éviter et les pratiques à appliquer pour aller plus loin dans l’optimisation de nos scripts.
Une histoire de portée
La portée des variables (ou scope), c’est leur domaine d’existence. Une variable peut être globale à tout un script ou être uniquement locale à une fonction. En JavaScript, on déclare une variable locale grâce au mot-clé var. Sans ce mot-clé, la variable sera considéré comme globale.
Comment JavaScript va-t-il chercher en mémoire les valeurs allouées aux variables que l’on a déclarées ? Il faut savoir que chaque fonction appelée crée un environnement de variable, qui sera détruit à la fin de la fonction. Ainsi, si une fonction est appelée dans une autre, un contexte d’exécution est encore créé, ainsi de suite, créant une chaîne. Plus la variable que l’on veut accéder est loin dans la chaîne, plus de temps mettra la résolution de la valeur. Une variable globale par exemple, est accessible partout, ce qui la contraint donc d’être en bout de chaîne. La résolution d’une variable globale sera donc plus lente que celle d’une variable locale.
On peut donc en tirer des conclusions pour optimiser nos scripts. Tout d’abord, essayez de n’utiliser qu’un minimum de variables globales. Précédez systématiquement vos variables du mot-clé var pour les déclarer locales, et enlever le par la suite si c’est vraiment nécessaire. Une erreur que l’on peut faire souvent : la déclaration de la variable d’incrémentation dans une boucle for. Si nous ne spécifions pas var, la variable sera considérée comme globale !
for(var i=0 ; i<10 ; ++i) { }Si vous devez accéder plusieurs fois à une variable qui est en dehors du contexte de la fonction, et en particulier une variable globale, il serait judicieux de la stocker dans une variable locale, et réutiliser celle-ci ensuite. Par exemple, lors d'appel successif à document ou window.
var divs = document.getElementsByTagName('div');
var pgfs = document.getElementsByTagName('p');
var imgs = document.getElementsByTagName('img');
var doc = document;
var divs = doc.getElementsByTagName('div');
var pgfs = doc.getElementsByTagName('p');
var imgs = doc.getElementsByTagName('img');
Pour ces mêmes raisons d'accès au scope, il est mieux d'éviter les structures with et catch qui, même si elles peuvent être pratiques, créent un autre contexte d'exécution, et éloignent vos variables d'un cran.
Accès aux données
Il y a différentes sortes de stocker de l'information en js. Vous pouvez stocker une valeur litérale (int, string, …) dans une variable. Mais vous pouvez également utiliser des structures de données plus complexes comme les tableaux (array) ou les objets (object).
Il faut savoir qu'accéder à un item d'un array ou d'une propriété d'un objet est plus coûteux qu'un simple accès à une variable contenant une valeur litérale. Si vous accéder plusieurs fois à la même information, stockez-la dans une variable locale, pour de meilleures performances.
Aussi, plus la profondeur d'un tableau ou d'un objet est grande, plus le temps de résolution sera important. Essayez donc d'étaler vos données plutôt à « l'horizontale ». Bien sûr, il faudra doser cette optimisation pour garder un code lisible et maintenable.
var infos = {
personne : ['prenom' => 'Be','nom' => 'wype','age' => 1],
adresse : 'ici',
fonction : 'blog'
}
if(infos.personne.nom.length == 4) {
connexion(infos. personne.nom) ;
enregistrement(infos. personne.nom) ;
affichage(infos. personne.prenom+' '+infos. personne.nom+', '+infos. fonction) ;
}
var infos = {
prenom : 'Be',
nom : 'wype'
age : 1,
adresse : 'ici',
fonction : 'blog'
}
var nom = infos.personne.nom;
if(nom == 4) {
connexion(nom) ;
enregistrement(nom) ;
affichage(infos.prenom+' '+nom+', '+infos.fonction) ;
}
Ce changement est bénéfique dès lors que l'on accède plus d'une fois à la même valeur d'un tableau ou d'un objet. Le gain est bien sûr multiplié si le code contient des boucles.

Repaint et Reflow
Commençons par définir ces deux termes, je vois que certains froncent les sourcils.
- Repaint
- C'est quand le navigateur redéfinit l'apparence d'un objet. Un changement de style css sur des propriétés tels que background, color, border-color... Cette opération est assez lente, car le navigateur doit réafficher l'élément modifié.
- Reflow
- Cette fois, c'est la forme de l'objet que le navigateur redéfinit. Lorsque l'on ajoute ou l'on enlève un élément du DOM par exemple. Il survient aussi avec des changements de style sur des propriétés tels que width, height, display… Un reflow d'un élément entraîne le reflow de ses enfants, ainsi que celui de ses ancêtres dans le DOM. Finalement, lors d'un reflow, le navigateur doit souvent réafficher tout le DOM, c'est donc une opération très lente.
Les interactions avec l'utilisateur sont l'un des intérêts principaux du JavaScript, il n'est donc pas question d'essayer de limiter les changements de DOM, ou les animations. Par contre, on peut optimiser nos scripts en regroupant ces changements pour limiter le nombre de repaint et reflow. Comme nous l'avons vu dans l'article précédant, n'hésitons pas à déléguer au css ces changements de style. Dans l'exemple suivant, nous passons ainsi de 3 à 1 seul reflow.
var monDiv = document.getElementById('monDiv') ;
monDiv.style.width = '100px';
monDiv.style.height = '200px';
monDiv.style.margin = '10px 0px 15px 5px';
var monDiv = document.getElementById('monDiv') ;
monDiv.className = 'maClasseCss';
De même pour les ajouts ou suppression d'élément du DOM. Regroupez par exemple les éléments que vous voulez ajouter au DOM et n'appelez qu'une seule fois la fonction append.
A votre tour
Avec tout ce que nous avons vu ensemble, vous avez déjà une belle palette d'optimisation à vos scripts. L'utilisation de librairies javascript comme Prototype ou jQuery aide grandement l'utilisation de javascript et accélère la rapidité de développement. Bien entendu, cette surcouche rajoute de la complexité dans les algorithmes déployés et la vitesse en prend un coup. Encore une fois, de bons réflexes pour optimiser l'utilisation de ces framework js sont à prendre pour trouver le bon compromis entre optimisation des performances, maintenabilité et temps de codage. Ces précieux dixièmes de seconde vous paraitront peut-être stupides, mais ils ne le seront certainement pas pour votre visiteur en 512k sur IE 6... Bon ok, lui il abuse peut-être. Mais l'intérêt d'optimiser ne va pas disparaître avec l'augmentation des performances des machines clientes. On ne peut ignorer aujourd'hui la volonté de Google de promouvoir l'internet rapide : on commence à parler de bonus de référencement pour les sites dont le temps de chargement est optimisé. Qu'en pensez-vous ?
Flux RSS de design, referencement, actus internet - Bewype
Recevez les articles tout chauds sortis du four !
Inscrivez-vous à notre flux RSS
Partager - Faîtes découvrir le blog Bewype - conception site internet et logique entrepreneuriale
Jeter un oeil sur les autres articles : design graphique, actu web et marketing seo
Vos commentaires sur JavaScript, les bonnes pratiques : optimiser vos scripts (2/2)
(5) performance,javascript,optimisation - Réagissez !-
Marius, Tennis en live
12 décembre 2010 à 12 h 47 min
Merci pour votre tutorial, vous avez perdu beaucoup de l’ecrire. Est-que vous pouvez pare un avec le PHP? Merci
-
Mathieu, Stylo
7 janvier 2011 à 14 h 33 min
Et 2 choses chose très importantes que j’ai notées dans mes expériences.
Tant que possible, charger les JS à la FIN des pages et, si possible, tout charger en un seul fichier.
jQuery est juste une plaie en terme de volume, avec ou sans CDN.
-
assistance informatique
28 juin 2011 à 0 h 00 min
Merci pour ces quelques astuces, c’est peut etre mieux que du css pas toujours compatible tout navigateurs