Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

is delegate the fastest way of binding?

Could someone explain why delegate seems faster than alias binding or on().

This is a test case:

jsPerf

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

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

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

Checking jquery source, it seems like before binding any event, jquery check for delegates.

Is it a correct statement or is there anything else?

like image 303
A. Wolff Avatar asked Apr 16 '13 18:04

A. Wolff


2 Answers

The error you made was to think there was only one p element.

I added another test, with only console.log($('p').length); and it showed that there was 7 p visible from the test, whose visibility was obviously not limited to the HTML you built in the preparation code.

This means that the two first functions had to do 7 more bindings.

like image 142
Denys Séguret Avatar answered Sep 22 '22 01:09

Denys Séguret


Both delegate() and bind() simply call on(). Here's an excerpt from the 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 );
},

So on() should be slightly faster than the other two functions, since it's one less function call. The actual invocation of the handler should be identical no matter which way it was bound.

But make sure you're comparing apples with apples. If you give a selector argument to delegate or bind, invoking the handler will be slower because it has to check whether the target satisfies the selector.

The reason for your benchmark result is because

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

is equivalent to something like:

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

It has to find all the matching elements and bind a handler to them. The delegate() call only has to bind a handler to one element (the document); instead of finding all the elements at binding time, at the time the event occurs it does something like:

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

The use of on() that's equivalent to delegate() would be:

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

When you delegate from a large element like document, you're invoking the internal handler every time you click anywhere in the document, wasting time testing if you're over a p. This is why you should try to limit the scope of the element used in delegate to the smallest static element that contains all the dynamic elements you want to delegate to.

like image 34
Barmar Avatar answered Sep 18 '22 01:09

Barmar