Why not take Javascript event delegation to the extreme?

后端 未结 3 624
一生所求
一生所求 2020-11-27 19:31

By now most folks on this site are probably aware that:

$(\"#someTable TD.foo\").click(function(){
    $(e.target).doSomething();
});

is go

相关标签:
3条回答
  • 2020-11-27 20:00

    What you're missing is there are different elements of the performance.

    Your first example performs worse when setting up the click handler, but performs better when the actual event is triggered.

    Your second example performs better when setting up the click handler, but performs significantly worse when the actual event is triggered.

    If all events were put on a top level object (like the document), then you'd have an enormous list of selectors to check on every event in order to find which handler function it goes with. This very issue is why jQuery deprecated the .live() method because it looks for all events on the document object and when there were lots of .live() event handlers registered, performance of each event was bad because it had to compare every event to lots and lots of selectors to find the appropriate event handler for that event. For large scale work, it's much, much more efficient to bind the event as close to the actual object that triggered the event. If the object isn't dynamic, then bind the event right to the object that will trigger it. This might cost a tiny bit more CPU when you first bind the event, but the actual event triggering will be fast and will scale.

    jQuery's .on() and .delegate() can be used for this, but it is recommended that you find to an ancestor object that is as close as possible to the triggering object. This prevents a buildup of lots of dynamic events on one top level object and prevents the performance degradation for event handling.

    In your example above, it's perfectly reasonable to do:

    $("#someTable").on('click', "td.foo", function(e) {
        $(e.target).doSomething();
    });
    

    That would give you one compact representation of a click handler for all rows and it would continue to work even as you added/removed rows.

    But, this would not make as much sense:

    $(document).on('click', "#someTable td.foo", function(e) {
        $(e.target).doSomething();
    });
    

    because this would be mixing the table events in with all other top level events in the page when there is no real need to do that. You are only asking for performance issues in the event handling without any benefit of handling the events there.

    So, I think the short answer to your question is that handling all events in one top level place leads to performance issues when the event is triggered as the code has to sort out which handler should get the event when there are a lot of events being handled in the same place. Handling the events as close to the generating object as practical makes the event handling more efficient.

    0 讨论(0)
  • 2020-11-27 20:15
    • If you remove a node, the corresponding listeners are not removed automatically.
    • Some events just don't bubble
    • Different libraries may break the system by stopping event propagation (guess you mentioned that one)
    0 讨论(0)
  • 2020-11-27 20:17

    If you were doing it in plain JavaScript, the impact of random clicks anywhere on the page triggering events is almost zero. However in jQuery the consequence could be much greater due to the amount of raw JS commands that it has to run to produce the same effect.

    Personally, I find that a little delegation is good, but too much of it will start causing more problems than it solves.

    0 讨论(0)
提交回复
热议问题