Mavimo ha recentemente scritto un interessantissimo post sul suo blog riguardo alle prestazioni dei selettori jQuery. Mi è servito come spunto per analizzare la questione delle performance, importantissima soprattutto in ambienti con risorse limitate come i cellulari/pda.

Analizzando il codice inserito da Mavimo possiamo notare come la più grande differenza tra i due selettori è che il primo non utilizza i context, mentre il secondo si. In altre parole

{syntaxhighlighter brush: javascript} $(‘#menu-container a’).each(function () { /* */ }); {/syntaxhighlighter}

Effettua prima il parsing della “formula” css like, poi cerca l’elemento con ID “#menu-container” in tutto il documento e infine cerca tutti i tag ‘a’ al suo interno.

Il secondo selettore, ovvero {syntaxhighlighter brush: javascript} $(‘a’, ‘#menu-container’).each(function () { /* */ }); {/syntaxhighlighter}

usa il context #menu-container, ovvero cerca tutti i tag ‘a’ usando come contesto la funzione nativa getElementByID(), che è ovviamente più veloce.

Qui sotto altri test con la libreria jQuery 1.4.2/1.3.2 (browser: Firefox 3.6.2)

{syntaxhighlighter brush: javascript} console.time(“select element nested”); for(var i = 0; i < 10000; i++ ) { $(‘a’, ‘#menu_container’); }; console.timeEnd(“select element nested”); {/syntaxhighlighter} Time: 741ms/828ms

{syntaxhighlighter brush: javascript} console.time(“select element w/o context”); for(var i = 0; i < 10000; i++ ) { $(‘#menu_container a’); }; console.timeEnd(“select element w/o context”); {/syntaxhighlighter} Time: 1362ms/1543ms

{syntaxhighlighter brush: javascript} console.time(“select element cached+find”); for(var i = 0; i < 10000; i++ ) { var elem = $(‘#menu-container’); elem.find(‘a’); }; console.timeEnd(“select element cached+find”); {/syntaxhighlighter} Time: 716ms/1044ms

{syntaxhighlighter brush: javascript} console.time(“select element cached+find”); for(var i = 0; i < 10000; i++ ) { $(‘#menu-container’).find(‘a’); }; console.timeEnd(“select element cached+find”); {/syntaxhighlighter} Time: 914ms/795ms

{syntaxhighlighter brush: javascript} console.time(“select element cached+find”); var elem = $(‘#menu-container’); for(var i = 0; i < 10000; i++ ) { elem.find(‘a’); }; console.timeEnd(“select element cached+find”); {/syntaxhighlighter} Time: 575ms/629ms

Il testo è stato effettuato su questa pagina (http://drupal.org/project/install_profile_api) e effettivamente non ho rilevato le grandi differenze riscontrate da mavimo tra i due metodi.

Per chiudere, il vantaggio va totalmente a perdersi nel caso si usino selettori multipli come context, anzi, cosa per me per ora inspiegabile il metodo a context è perfino più lento.

{syntaxhighlighter brush: javascript} console.time(“selector1”); for(var i = 0; i < 10000; i++ ) { $(‘a’, ‘#menu_container #link’); }; console.timeEnd(“selector1”); {/syntaxhighlighter} Time: 2131ms (1.3)

{syntaxhighlighter brush: javascript} console.time(“select element w/o context”); for(var i = 0; i < 10000; i++ ) { $(‘#menu_container #link a’); }; console.timeEnd(“select element w/o context”); {/syntaxhighlighter} Time: 1897ms (1.3)

Photo Credits: Peter Hellberg