Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
187 views
in Technique[技术] by (71.8m points)

javascript events - How does jQuery's new on() method compare to the live() method in performance?

jQuery has a new method called on() that is recommended to replace delegate(), live(), and .bind().

For example, using both methods:

$('#some-button').on('click', function() {
    //do something when #some-button is clicked
});
$('#some-button').live('click', function() {
    //do something when #some-button is clicked
});

Which one performs better? (I do know that both of these event contexts are at the document level.)

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

As I understand .live() and .on(), the two examples you have included do not so the same thing.

Your first one:

$('#some-button').on('click', function() {
    //do something when #some-button is clicked
});

does not have a live behavior. It finds the #some-button object and installs an event handler on it directly. This is very efficient, but does not have .live() behavior. If the #some-button object does not exist at this time, no event handler will be installed ever. It is basically the same as this:

$('#some-button').click(function() {
    //do something when #some-button is clicked
});

Your second one:

$('#some-button').live('click', function() {
    //do something when #some-button is clicked
});

has live behavior. It installs an event handler on the document and waits for clicks targeted to an object that matches "#some-button" to bubble up to the document object. Your second one is theoretically equivalent to this:

$(document).on('click', '#some-button', function() {
    //do something when #some-button is clicked
});

I say theoretically equivalent because it should install the same event handlers, but I don't know if the jQuery code for processing the two is identical or not.

One of the reasons that .live() has been deprecated is that it can be a bad thing to have a lot of .live() handlers because you get a lot of event handlers on the document object. Then, every click or even mousemove that bubbles up to the document object has to be checked against a LOT of selectors which can really slow things down.

Another issue with .live() is that it evaluates the selector "#some-button" at the time you make the call, but doesn't actually use that result so it's wasteful. The .on() version doesn't evaluate the selector passed as an argument to .on() when you make the first call because it isn't needed at that time - it's only need later when an actual click comes in that has to be compared to the selector.

With the advent of .on() (or something you could previously do with .delegate()), you can target your "live" event handlers more efficiently by not putting them all on the document object, but rather putting them on a parent object that does not come and go and is a lot closer to where the real objects are such as this:

$('#some-button-parent').on('click', '#some-button', function() {
    //do something when #some-button is clicked ///////
});

This spreads the event handlers out to different objects and gets them closer to the actual objects for which they are meant meaning you don't end up with this giant list of event handlers that have to be checked against selectors on every mousemove or click event. That's why .live() has been replaced and deprecated. It's much better to use .delegate() or .on() and specify a parent object that isn't as far away as the document object.

The advantage of the new .on() syntax is that you can do both "live" and "static" event handlers with the same method now, just by varying how you pass the arguments. The jQuery object is where the event handler will be installed and the optional selector in the second argument is a selector that the event target must match. If you pass that selector, then all events hitting the object(s) specified in the jQuery object will have their target checked against that selector. If there is no selector, then only objects who's target is the same as the object specified in the jQuery object will be matched.

So, this is all the theory about how they work and why one configuration is supposed to be better than another. If you want to test real world performance, you'd have to devise some sort of performance test on event handler propagation and distribution probably in a scenario where you had a lot of "live" event handlers. That test is probably not easy to do because it may be hard to get timing info on the start/end of an event handler. You can't easily use a tool like jsperf for something like this.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...