Search code examples
javascriptperformanceevent-handlingdelegationevent-bubbling

Can I improve jQuery performance by combining all events of same type into one handler?


I have a jQueryMobile site/app where performance is an issue. I am reading a lot about how it's smart not to bind too many separate handlers. So if you have a page with a lot of buttons , the advice is to bind like this...

$(document).on('click',function(){
   if (this = $('#button1')){
       //Handler for button one
   } else if (this = $('#button2') {
       //etc
   } else //etc
})

...rather than like this...

$('#button1').click(function(){
    //Handler for button one
})
$('#button2').click(function(){
    //Handler for button two
})
//etc

So I am wondering to what extent this is truly useful.

What if I made one listener for all 'pageshow' events in my document? (a jQueryMobile website is a single document containing many pages, and many of those pages need a bit of dolling up around showtime).

What if I made one click listener for all forty-odd buttons in the document, and used the handler to distinguish which button we're dealing with and what needs to be done in response?


Solution

  • Your first option is faster to install and initialize, but slower to run when an event happens.

    If you had hundreds of buttons with all nearly identical event handling, it might make sense to only install one event handler for all of them rather than run the code to install hundreds of event handlers. But, you would still pay a small performance penalty when a particular event happens.

    If you want to maximally optimize for run-time performance at the time of an event, it is still faster to install an event handler on the specific object you want to monitor. That's because the event handlers are kept in a separate list just for that object and the code doesn't have to sort through a long list of event handlers to find which one is appropriate for that specific object and event.

    Also, your if statement in the first option will never work for several reasons. It would need to be something like this:

    $(document).on('click',function(e) {
       if (e.target.id == 'button1') {
           //Handler for button one
       } else if (e.target.id == 'button2') {
           //etc
       } 
    })
    

    And, anytime you use delegated event handling, it's better to pick a common parent for the buttons that is much closer to the actual objects than the document object (helps runtime performance).

    $("#buttonContainer").on('click',function(e) {
       if (e.target.id == 'button1') {
           //Handler for button one
       } else if (e.target.id == 'button2') {
           //etc
       } 
    })
    

    If you wanted just button clicks with delegated event handling, you could use some of the delgation features built into .on() like this

    $("#buttonContainer").on('click', 'button', function(e) {
       if (this.id == 'button1') {
           //Handler for button one
       } else if (this.id == 'button2') {
           //etc
       } 
    })