Prototype Vs Closure - optimisation d'une classe en JavaScript
En JavaScript, il y a 2 grandes façons de faire une classe : le mode prototype et le mode closure.
Méthode closure :
var Foo = function(){
this.method = function(){
return 'test';
}
}
Méthode prototype :
var Foo = function(){
}
Foo.prototype.method = function(){
return 'test';
}
Dans les 2 cas, on peut utiliser l'objet de la même façon.
var foo = new Foo();
foo.method();
Pourquoi est-il conseillé d'utiliser la méthode prototype plutôt que la méthode closure ?
C'est principalement une question de performances. Lors de la création d'un objet "closure", le constructeur est parsé/executé, il y a donc création des différentes méthodes qui appartiennent alors à l'instance de l'objet. Avec une classe "prototype" les méthodes sont déjà instanciées lors de la création du type et appartiennent à l'instance du prototype de l'objet, deux instances d'une même classe partagent le même prototype. Cela a deux incidences :
- La création de l'objet sera plus longue à cause de la création des méthodes membres.
- L'instance de l'objet prendra plus de mémoire car les méthodes membres ne sont pas partagées entre les objets.
Pour le prouver j'ai créé 100 000 instances de Foo puis regardé la consommation mémoire ainsi que le temps de création.
| |
prototype |
closure |
| IE7 |
25 332 ko |
568 ms |
108 900 ko |
976 ms |
| FF2 |
39 612 ko |
953 ms |
56 976 ko |
1 236 ms |
| Opera 9.23 |
25 008 ko |
284 ms |
45 882 ko |
674 ms |
| Safari 3.0.3 |
55 820 ko |
240 ms |
59 124 ko |
333 ms |
J'ai relancé le navigateur entre chaque test. Voici le code utilisé :
var foos = [];
var d = new Date();
for (var i = 0; i < 100000; i++){
foos.push(new Foo());
}
alert((new Date()) - d);
La classe utilisé pour les tests est très simple, mais lorsqu'il s'agit d'objet complexe avec des dizaines de méthodes qui contiennent des dizaines de lignes, alors c'est tout ce contenu qui sera dupliqué en mémoire pour chaque instance.
Si vous utilisez des classes JavaScript et que vous utilisez le mode closure, vous savez maintenant comment optimiser votre application JavaScript ...
Dans les version betas de Microsoft Ajax (Atlas), le mode closure était utilisé. Bertrand Leroy a publié sur son blog un guide de migration du mode closure vers le mode prototype (part 1) et (part 2).