Quick Performance Tip: jQuery and addClass

Abstractions are helpful and dangerous. But the more we know about a library’s internals, the less danger we’ll be in later. Here’s an issue I ran into where I had assumed that jQuery would be optimized for this case, but it wasn’t. I’ll go over my bad assumption and how to workaround it.

As of jQuery 1.3.2, adding multiple HTML classes to an element using jQuery’s addClass method will add them one at a time, modifying the className property of an element for each class.

$('#myElement').addClass('myFirstClass mySecondClass');

Here’s the original code inside of jQuery 1.3.2. Note how the classNames string is split, and elem.className is changed for each split entry.

add: function( elem, classNames ) {
    jQuery.each((classNames || "").split(/\s+/), function(i, className){
        if ( elem.nodeType == 1 && !jQuery.className.has( elem.className, className ) )
            elem.className += (elem.className ? " " : "") + className;
        });
    },
// ...

This may cause longer than needed delays, as reflow may occur after every class is added individually. If absolutely necessary, you can always fall back to modifying the className yourself, like so:

$('#myElement').each(function()
{
   this.className += ' myFirstClass mySecondClass';
});

Most likely, this isn’t a tip that will be needed, but it is useful to be aware of.

VN:F [1.8.4_1055]
Rating: 3.8/5 (11 votes cast)
Quick Performance Tip: jQuery and addClass3.8511
This entry was posted in JavaScript and tagged , . Bookmark the permalink. Post a comment or leave a trackback: Trackback URL.
  • Thanks for reading. If you found this article useful, and you've read through some of my previous articles, you might as well Subscribe to my content subscribe to my blog. You'll save me some bandwidth that way.

2 Comments

  1. Posted August 12, 2009 at 1:36 am | Permalink

    Great insight, and kudos to you for actually delving into the underlying source code.

    I, myself, have been writing some code that dynamically modifies classes of some HTML elements as part of an event procedure (namely, hover in and out). As you can imagine, the performance load on this can get pretty hefty; it increases proportionally the more classes you add in and the more elements you modify in one go. This is most notable in Internet Explorer too.

    While your aforementioned workaround for the .addClass() procedure would definitely work better in my opinion, I also wanted to ask if there was a better way to implement .removeClass() as well. Manually doing this meant string splitting and concatenation, which, I assume, is what the function already does.

    Good work, and definitely bookmarking this.

  2. Zach Leatherman
    Posted August 13, 2009 at 5:24 pm | Permalink

    Richard,
    I’m surprised you’re seeing performance issues inside callbacks for hover events. How many nodes are in the DOM tree you’re modifying the className for?

    Actually, it looks like the removeClass method is optimized, and only sets the string once, instead of multiple times. It shouldn’t need any changes.

    elem.className = classNames !== undefined ?
    	jQuery.grep(elem.className.split(/\s+/), function(className){
    		return !jQuery.className.has( classNames, className );
    	}).join(" ") :
    	"";

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="">

Additional comments powered by BackType