Skip to main content

Is binding events in jQuery very expensive, or very inexpensive?



I just wrote a $().bind('event') function and then got concerned that this kind of a call might be very expensive if jQuery has to run through each element in the DOM to bind this event.





Or maybe, it's just about as efficient as an event could be. The jQuery docs I've read aren't making this clear. Any opinions?



Source: Tips4all

Comments

  1. There are two things that can make your event binding code slow: the selector and the # of bindings. The most critical of the two is the # of bindings, but the selector could impact your initial performance.

    As far as selectors go, just make sure you don't use pure class name selectors like .myclass. If you know that the class of myclass will always be in a <div> element, make your selector be div.myclass as it will help jQuery find the matching elements faster. Also, don't take advantange of jQuery letting you give it huge selector strings. Everything it can do with string selectors it can also do through functions, and this is intentional, as it is (marginally, admittedly) faster to do it this way as jQuery doesn't have to sit around to parse your string to figure out what you want. So instead of doing $('#myform input:eq(2)'); you might do $('input','#myform').eq(2);. By specifying a context, we are also not making jQuery look anywhere it doesn't have to, which is much faster. More on this here.

    As far as the amount of bindings: if you have a relatively medium-sized amount of elements then you should be fine - anything up to 200, 300 potential element matches will perform fine in modern browsers. If you have more than this you might want to instead look into Event Delegation.

    What is Event Delegation? Essentially, when you run code like this:

    $('div.test').click(function() {
    doSomething($(this));
    });


    jQuery is doing something like this behind the scenes (binding an event for each matched element):

    $('div.test').each(function() {
    this.addEventListener('click', function() {
    doSomething(this);
    }, false);
    });


    This can get inefficient if you have a large amount of elements. With event delegation, you can cut down the amount of bindings done down to one. But how? The event object has a target property that lets you know what element the event acted on. So you could then do something like this:

    $(document).click(function(e) {
    var $target = $(e.target);
    if($target.is('div.test')) { // the element clicked on is a DIV
    // with a class of test
    doSomething($target);
    }
    });


    Thankfully you don't actually have to code the above with jQuery. The live function, which is advertised as an easy way to bind events to elements that do not yet exist, is actually able to do this by using event delegation and checking at the time an action occurs if the target matches the selector you specify to it. This has the side effect, of course, of being very handy when speed is important.

    The moral of the story? If you are concerned about the amount of bindings your script has just replace .bind with .live and make sure you have smart selectors.

    Do note, however, that not all events are supported by .live. If you need something not supported by it, you can check out the livequery plugin, which is live on steroids.

    ReplyDelete
  2. Basically, you're not going to do any better.
    All it is doing is calling attachEventListener() on each of your selected elements.

    On parse time alone, this method is probably quicker than setting inlined event handlers on each element.

    Generally, I would consider this to be a very inexpensive operation.

    ReplyDelete

Post a Comment

Popular posts from this blog

[韓日関係] 首相含む大幅な内閣改造の可能性…早ければ来月10日ごろ=韓国

div not scrolling properly with slimScroll plugin

I am using the slimScroll plugin for jQuery by Piotr Rochala Which is a great plugin for nice scrollbars on most browsers but I am stuck because I am using it for a chat box and whenever the user appends new text to the boxit does scroll using the .scrollTop() method however the plugin's scrollbar doesnt scroll with it and when the user wants to look though the chat history it will start scrolling from near the top. I have made a quick demo of my situation http://jsfiddle.net/DY9CT/2/ Does anyone know how to solve this problem?

Why does this javascript based printing cause Safari to refresh the page?

The page I am working on has a javascript function executed to print parts of the page. For some reason, printing in Safari, causes the window to somehow update. I say somehow, because it does not really refresh as in reload the page, but rather it starts the "rendering" of the page from start, i.e. scroll to top, flash animations start from 0, and so forth. The effect is reproduced by this fiddle: http://jsfiddle.net/fYmnB/ Clicking the print button and finishing or cancelling a print in Safari causes the screen to "go white" for a sec, which in my real website manifests itself as something "like" a reload. While running print button with, let's say, Firefox, just opens and closes the print dialogue without affecting the fiddle page in any way. Is there something with my way of calling the browsers print method that causes this, or how can it be explained - and preferably, avoided? P.S.: On my real site the same occurs with Chrome. In the ex