Which is faster, .on() or .click()?

2019-05-11 17:22发布

问题:

If I have a table with links to delete a record, which is the best way to wire up the click event? Do these evaluate the same under the hood?

$("#table").on("click", ".delete", function(){
   //do stuff
});

or

$("#table .delete").click(function(){
   //do stuff
});

回答1:

No, they don't.

In the way you are using them...

.on() The way you are using it (delegation), will save you cycles at attachment as well as memory, because it doesn't actually attach the events in that moment, as it provides a dynamic element where the event is applied to future elements as well.

.click() will save you cycles at execution, as it explicitly attaches an event to every matching element at that moment in time, but in reality, this would be the last place I'd look for a bottleneck.

Read some testing with event delegation here...

Performance testing of attaching event handlers...



回答2:

It's like asking what is faster int or string in C#. Each type has it's uses...
It's not about which is faster, it's about what to use when.

on allows you to attach event to dynamically added elements while click does not.

if you don't have "dynamically added elements" use click, otherwise use on.



回答3:

click is faster that on because it attaches the event directly on the element where as on is attaching the event on #table and looking for .delete element to trigger the event so there is some code execution involved before the click event is triggered.

The difference is negligible though you will not see any difference.

If you use on the only one event handler is enough to take care of any number of .delete elements inside the #table where as click will be attached to each of the .delete elements so on better in terms of memory utilization.



回答4:

In this particular scenario, the .click(...) will (likely) be slower, because it will need to iterate through each row and each cell that matches the selector, and attach the handler function to each one. The on(...), in this particular case, is likely to be faster, because it attaches the handler to the table, not to each element that has the .delete class.

That being said, you need to consider a few things when choosing between these two:

  1. How complex is your selector? If you are doing $('#rootItem').on('click', '.foo .bar.baz .bum', function() { /* do stuff*/ }), this will be inherently slower than $('#rootItem').on('click', '.foo', function() { /* do stuff*/ }) because the selector is more complex in the former case. In this kind of scenario, it might make more sense to pay the price on attachment and use click(...) to save the run-time cost of evaluating every click within #rootItem to see if it matches the selector '.foo .bar.baz .bum'. A simple single-class selector like you have ('.delete') will perform just fine.
  2. Will the contents be changing dynamically? If so, you'll be responsible for calling click(...) on each dynamically-added item. The on(...) function can handle this a little better, as long as your "outside" selector ('#table' in this case) doesn't point at elements that will be dynamically added. Replace '#table' with '.table', and dynamically add a new table with class table, and the newly-added table won't have event handlers attached to it from your initial call to on(...).