2010-11-24 1 views
9

Diciamo che ho $('mySelector:first'); e $('mySelector').first();. Qual è il modo più efficiente? Ho cercato nella fonte, ma non riuscivo ancora a capirlo.jQuery cosa è più veloce: selettori o metodi?

Sembra che nel primo caso jQuery passa attraverso ogni elemento fino a quando ottiene la prima:

CHILD: function(elem, match) { 
     var type = match[1], 
     node = elem; 
     switch (type) { 
      ... 
     case "first": 
      while ((node = node.previousSibling)) { 
      if (node.nodeType === 1) { 
      return false; 
      } 
      } 
      if (type === "first") { 
      return true; 
      } 
      node = elem; 
       ... 
     } 
} 

Nel secondo caso jQuery fette la raccolta, ma non sono sicuro di come è efficiente:

function first() { 
    return this.eq(0); 
}; 

function eq(i) { 
    return i === -1 ? 
    this.slice(i) : 
    this.slice(i, +i + 1); 
}; 
+1

La differenza di velocità è così minima che non avrà alcuna importanza. – Alex

+0

@Phrogz che è davvero ossessivo. – Raynos

+1

@Raynos Grazie (?) :) – Phrogz

risposta

12

L'attuale risposta accettata non è coerente con il confronto tests across many browsers:first e :eq(0)-.first() e .eq(0).

per i principali browser desktop:
$('foo').first() è quasi quattro volte più veloce rispetto $('foo:first')

Se si vuole esaminare la metodologia, here are the tests and their current results.

+1

Buon punto, darò la risposta a te, a meno che shamittomar non possa fornire i suoi test. –

+1

Yay per risposte guidate dai dati! +1. – Yahel

0

Nel mio test, $('mySelector:first'); è più velocemente di quanto$('mySelector').first();

Si può un essere interessato anche a this;

+2

Link molto buono, grazie. Ora ho intenzione di ottimizzare i miei selettori =) Ti dispiace condividere i test? –

+1

Hai testato su diversi browser, versioni e SO? Hai testato su documenti con un singolo elemento abbinato rispetto a 10s e 100s? – Phrogz

0

Confronta $('li:first') a $('li').first(), scommetto che il primo deve essere più veloce. Perché, ad esempio, in un documento contenente 100 li, la seconda query crea semplicemente un elenco di 100 elementi e quindi restituisce il primo da esso; d'altra parte, la prima query si fermerà proprio lì dopo che viene restituito il primo li.

Anche la query viene gestita in modo nativo dal browser, richiede ancora più memoria rispetto alla prima.

+0

Inoltre, i selettori CSS saranno eventualmente implementati dal browser, il che lo renderà ancora più veloce. –

+2

La tua logica è ipoteticamente valida, ma hai esaminato la fonte Sizzle per assicurarti che la pseudo-classe ': first' venga applicata durante la ricerca, e non dopo aver trovato l'intero set? – Phrogz

2

Il secondo dovrebbe recuperare TUTTI gli elementi nel selettore prima di ottenere il primo. Quindi, se il selettore fosse di 10.000 elementi, recupererebbe tutti i 10.000, quindi il primo da quel gruppo. Mi auguro che il primo sia migliore in questo senso poiché filtra mentre cerca (e si ferma dopo che il primo è stato trovato). Probabilmente è banale nella maggior parte dei casi, però.

Naturalmente se si sta funzioni concatenano allora può essere inevitabile:

$('.someclass').addClass('otherClass').first().addClass('firstClass');