Optimiser vos boucle for avec JavaScript
JavaScript est un langage "late binded" c'est à dire que chaque appel d'une propriété aura un coût et ne sera pas mis en cache.
Pour le prouver voici un exemple :
window.pageLoad = function() {
var a = [];
for(var i = 0; i < 1000000; i++){
a.push(i);
}
if (true){
// boucle N°1
var start = new Date();
for(var i = 0; i < a.length; i++){
}
alert(new Date() - start);
} else {
// boucle N°2
start = new Date();
for(var i = 0, l = a.length; i < l; i++){
}
alert(new Date() - start);
}
}
La différence ce situe au niveau de la condition de fin, au lieu de vérifier à chaque fois a.length, j'ai mis cette valeur en cache dans la variable l. (le if(true) permet seulement de basculer d'un test à un autre)
Voici les résultats (en ms) :
| |
IE 7 vista |
FF 2.0.0.11 |
Opera 9.24 |
Safari 3.0.4 |
| Boucle N°1 |
220 |
115 |
160 |
170 |
| Boucle N°2 |
85 |
60 |
90 |
140 |
Voici un exemple encore plus parlant
window.pageLoad = function() {
var a = {b:{c:{d:{e:{f:{g:{h:{i:{j:{k:{l:{m:{n:{o:{p:{q:{r:{s:{t:{u:{v:{w:{x:{y:{z:100000}}}}}}}}}}}}}}}}}}}}}}}}};
if (false){
// boucle N°1
var start = new Date();
for(var i = 0; i < a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y.z; i++){
}
alert(new Date() - start);
} else {
// boucle N°2
var start = new Date();
for(var i = 0, l = a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y.z; i < l; i++){
}
alert(new Date() - start);
}
}
| |
IE 7 vista |
FF 2.0.0.11 |
Opera 9.24 |
Safari 3.0.4 |
| Boucle N°1 |
290 |
85 |
80 |
100 |
| Boucle N°2 |
9 |
7 |
8 |
13 |
On voit ici l'intérêt de mettre en cache des variables "profondes".
Je met souvent en cache mes variables lorsque je dois modifier une propriété d'un noeud DOM, typiquement dans le cas d'une animation, on sait qu'on va modifier la propriété xxx de la propriété style d'un noeud DOM un bon nombre de fois, il est donc nécessaire de mettre en cache cette propriété style pour avoir des performances acceptable.
D'autres astuces de performances JS :