2013-04-16 19 views
6

Könnte jemand erklären, warum Delegat schneller als Alias-Bindung oder on() scheint.ist Delegierter der schnellste Weg der Bindung?

Dies ist ein Testfall:

jsPerf

$('p').on('click',$.noop); //80% slower 

$('p').click($.noop); //84% slower 

$(document).delegate("p", "click",$.noop); //fastest 

jquery Quelle prüfen, wie es scheint, bevor sie irgendein Ereignis, jquery Scheck für die Teilnehmer verbindlich.

Ist es eine korrekte Aussage oder gibt es noch etwas?

+2

Versuchen Sie, 'delegate' auf etwas einzustellen, das Sie suchen müssen. – Musa

+0

Da 'delegate()' 'on()' aufruft (sie sind bis auf die Reihenfolge der Argumente äquivalent), kann es auf keinen Fall effizienter sein. – Barmar

+1

Beachten Sie, dass das Problem nicht darin besteht, nach den "p" -Elementen zu suchen: http://jsperf.com/test-on-click-delegate/2 –

Antwort

6

Der Fehler gemacht werden war zu denken, dass es nur ein p Element gab.

Ich fügte einen weiteren Test hinzu, mit nur console.log($('p').length); und es zeigte, dass 7 p aus dem Test sichtbar war, dessen Sichtbarkeit offensichtlich nicht auf den HTML-Code beschränkt war, den Sie im Vorbereitungscode erstellten.

Dies bedeutet, dass die beiden ersten Funktionen 7 weitere Bindungen haben mussten.

+0

Das ist alles zu erklären, kluges Denken, danke, mein Herr! –

5

Sowohl delegate() als auch bind() rufen Sie einfach on(). Hier ist ein Auszug aus dem jQuery Quelle 1.9.0:

bind: function(types, data, fn) { 
    return this.on(types, null, data, fn); 
}, 
delegate: function(selector, types, data, fn) { 
    return this.on(types, selector, data, fn); 
}, 

So sollte on() geringfügig schneller als die beiden anderen Funktionen, da es eines ist weniger Funktionsaufruf. Der tatsächliche Aufruf des Handlers sollte identisch sein, egal auf welche Weise er gebunden wurde.

Aber stellen Sie sicher, dass Sie Äpfel mit Äpfeln vergleichen. Wenn Sie das Argument selector an delegate oder bind übergeben, wird das Aufrufen des Handlers langsamer, da überprüft werden muss, ob das Ziel den Selektor erfüllt.

Der Grund für die Benchmark-Ergebnis ist, weil

$("p").on('click',$.noop); 

zu so etwas wie gleichwertig ist:

$("p").each(function() { 
    $(this).on('click', $.noop); 
}); 

Es verfügt über alle passenden Elemente finden und einen Handler an sie binden. Der Aufruf delegate() muss nur einen Handler an ein Element (das Dokument) binden; statt finden alle Elemente an Bindezeit, die zum Zeitpunkt der Veranstaltung kommt es tut so etwas wie:

if ($(event.target).is("p")) { ... } 

Die Verwendung von on(), die delegate() gleichwertig ist wäre:

$(document).on('click', 'p', $.noop); 

Wenn Sie delegieren aus Ein großes Element wie document, Sie rufen den internen Handler jedes Mal auf, wenn Sie irgendwo in das Dokument klicken, und verschwenden Zeittests, wenn Sie über sind. Aus diesem Grund sollten Sie versuchen, den Gültigkeitsbereich des in delegate verwendeten Elements auf das kleinste statische Element zu beschränken, das alle dynamischen Elemente enthält, an die Sie delegieren möchten.

+1

Sie sagen, dass die Benchmark falsch ist? –

+0

Thx für Erklärung. Nach der Antwort von Dystroy bekomme ich es jetzt. –

5

Delegat ist nur schneller, weil Sie keine Elemente nachschlagen müssen, wenn Sie einen Selektor anstelle eines Elemente verwenden Delegierten wird die langsamste

<div> 
<p>test</p> 
</div> 


$('p').on('click',$.noop); 
$('p').click($.noop); 
$('div').delegate("p", "click",$.noop); 

http://jsperf.com/test-on-click-delegate/3

+0

Das ist wirklich ein guter Punkt! –

Verwandte Themen