2013-04-16 4 views
6

Quelqu'un pourrait-il expliquer pourquoi le délégué semble plus rapide que la liaison d'alias ou on().est délégué le moyen le plus rapide de liaison?

C'est un test:

jsPerf

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

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

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

Vérification source jquery, il semble que avant de se lier tout état de cause, chèque jquery pour les délégués.

Est-ce une affirmation correcte ou existe-t-il autre chose?

+2

Essayez de définir 'delegate' sur quelque chose que vous devez rechercher. – Musa

+0

Puisque 'delegate()' appelle 'on()' (ils sont équivalents à l'exception de l'ordre des arguments), il n'y a aucun moyen de le rendre plus efficace. – Barmar

+1

Notez que le problème n'est pas de rechercher les éléments 'p': http://jsperf.com/test-on-click-delegate/2 –

Répondre

6

L'erreur que vous avez fait était de penser qu'il n'y avait qu'un seul élément p.

J'ai ajouté un autre test, avec seulement console.log($('p').length); et il a montré qu'il y avait 7 p visible du test, dont la visibilité n'était évidemment pas limitée au code HTML que vous avez construit dans le code de préparation.

Cela signifie que les deux premières fonctions devaient effectuer 7 autres liaisons.

+0

C'est tout expliquer, pensée intelligente, merci monsieur! –

5

Les deux delegate() et bind() appellent simplement on(). Voici un extrait de la jQuery 1.9.0 source:

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); 
}, 

Alors on() devrait être légèrement plus rapide que les deux autres fonctions, car il est un appel de fonction moins. L'invocation réelle du gestionnaire devrait être identique quelle que soit la manière dont il était lié. Mais assurez-vous de comparer des pommes avec des pommes. Si vous attribuez un argument selector à delegate ou bind, l'appel du gestionnaire sera plus lent car il doit vérifier si la cible satisfait le sélecteur.

La raison de votre résultat de référence est parce que

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

équivaut à quelque chose comme:

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

Il doit trouver tous les éléments correspondants et lier un gestionnaire à eux. L'appel delegate() doit uniquement lier un gestionnaire à un élément (le document); au lieu de trouver tous les éléments au moment de la liaison, au moment où l'événement se produit, il fait quelque chose comme:

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

L'utilisation de on() qui est équivalent à delegate() serait:

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

Lorsque vous déléguez de un gros élément comme document, vous appelez le gestionnaire interne chaque fois que vous cliquez n'importe où dans le document, ce qui vous fait perdre du temps si vous avez dépassé p. C'est pourquoi vous devriez essayer de limiter la portée de l'élément utilisé dans delegate au plus petit élément statique qui contient tous les éléments dynamiques que vous souhaitez déléguer.

+1

Êtes-vous en train de dire que le benchmark est faux? –

+0

Thx pour explication. Après la réponse de dystroy, je l'obtiens maintenant. –

5

délégué est seulement plus rapide parce que vous n'avez pas à rechercher des éléments, si vous utilisez un sélecteur au lieu d'un délégué éléments sera le plus lent

<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

C'est vraiment un bon point! –

Questions connexes