O'Reilly logo

Supercharged JavaScript Graphics by Raffaele Cecco

Stay ahead with the world's most comprehensive technology and business learning platform.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, tutorials, and more.

Start Free Trial

No credit card required

Optimizing jQuery and DOM Interaction

jQuery is an extensively used JavaScript library and provides a concise, convenient, and flexible way of accessing and manipulating elements within the DOM. It is designed to mitigate cross-browser issues, allowing you to concentrate on core application development rather than fiddling with browser quirks. jQuery is built around a selector engine, which allows you to find DOM elements using familiar CSS-style selector statements. For instance, the following code returns a jQuery object (a kind of array) containing all image elements with a CSS class of big:

$images = jQuery('img.big');

or the jQuery shorthand notation way:

$images = $('img.big');

The $images variable is just that, a normal variable. The preceding $ is simply a reminder that it references a jQuery object.

There is one caveat to jQuery’s power: an apparently small and innocuous jQuery statement can do a lot of work behind the scenes. This might not be significant if a small number of elements is being accessed only occasionally. However, if many elements are being accessed on a continuous basis—for example, in a highly animated page—there can be serious performance implications.

Optimizing CSS Style Changes

A fundamental part of creating JavaScript graphics using DHTML is being able to quickly manipulate the CSS style properties of DOM elements. In jQuery, you can do this like so:


This would find the element whose id is element1 and change its CSS color style to red.

Scratching beneath the surface, there is a lot going on here:

  • Make a function call to jQuery and ask it to search the DOM for an element with id of element1. Apart from doing the search itself, this involves performing regular expression tests to determine the type of search required.

  • Return the list of items found (in this case, one item) as a special jQuery array object.

  • Make a function call to the jQuery css() function. This performs various checks such as determining whether it is reading or writing a style, whether it is being passed a string argument or object literal, and more. It finally updates the style of the element itself.

Performing this type of work many times in succession will be slow, regardless of how efficient jQuery is under the hood:

$('#element1').css('color','#f00');    // Make red.
$('#element1').css('color','#0f0');    // Make green.
$('#element1').css('color','#00f');    // Make blue.
$('#element1').css('left,'100px');     // Move a bit.

Each of the preceding lines performs a search for the element with id of element1. Not good.

A faster method is to specify a context within which jQuery should search for elements. By default, jQuery begins its searches from the document root, or the topmost level within the DOM hierarchy. In many instances, starting from the root level is unnecessary and makes jQuery do more searching than is required. When you specify a context, jQuery has less searching to do and will return its results in less time.

The following example searches for all elements with a CSS class of alien, beginning the search within the DOM element referenced in container (the context):

$aliens = $('.alien', container); // Search within a specific DOM element.

The context parameter type is flexible and could have been another jQuery object or CSS selector:

// Start search within the elements of the jQuery object, $container.
$aliens = $('.alien', $container);

// Look for an element with id of 'container' and start the search there.
$aliens = $('.alien', '#container');

Make sure that searching for the context is not slower than searching for the elements within it! It is better to reference the context DOM element directly where possible.

Ideally, once elements have been found, you should not search for them again at all. We can cache (reuse) the search results instead:

var $elem = $('#element1');    // Cache the search results.
$elem.css('color','#f00');     // Make red.
$elem.css('color','#0f0');     // Make green.
$elem.css('color','#00f');     // Make blue.
$elme.css('left,'100px');      // Move a bit.

This still leaves the jQuery css() function call, which is doing more work than is necessary for our purposes. We can dereference the jQuery search results right down to the actual style object of the DOM element:

// Get the first element ([0]) from the jQuery search results and store
// a reference to the style object of that element in elemStyle.

var elemStyle = $('#element1')[0].style;

// It is now quicker to manipulate the CSS styles of the element.
// jQuery is not being used at all here:

elemStyle.color = '#f00';       // Make red.
elemStyle.color = '#0f0';       // Make green.
elemStyle.color = '#00f';       // Make blue.
elemStyle.left = '100px';       // Move a bit.

Figure 1-7 shows the performance results of setting a CSS style for one DOM element via an uncached jQuery.css(), a cached jQuery.css(), or a direct write to the style object of the DOM element. The differences would be even more significant in more complex pages with slower CSS selectors—for example, $('.some-css-class').

Where speed is of the essence, manipulating an element’s properties directly will be faster than going through jQuery. For example, the jQuery.html() method can be considerably slower than using an element’s innerHTML object directly.

Speed comparison of using uncached jQuery, cached jQuery, and direct write to update an element’s CSS style. Bigger is better.

Figure 1-7. Speed comparison of using uncached jQuery, cached jQuery, and direct write to update an element’s CSS style. Bigger is better.

Do the results in Figure 1-7 imply that we shouldn’t be using jQuery at all? Not so; jQuery is far too good a library to reject, and it is understandably slow in certain circumstances. The rule is to be wary of how jQuery is used in time-critical areas of your application. This will usually be a small percentage of the total code. The majority of your application can and should use jQuery for quicker development, convenience, and fewer cross-browser issues.

Optimizing DOM Insertion

If you need to add a large number of elements into the DOM in your application, there can be performance implications. The DOM is a complex data structure that prefers being left alone. Of course, this is not really feasible in dynamic web pages, so you need an efficient way of inserting elements.

You can insert an element into the DOM with jQuery like this:

$('#element1').append('<p>element to insert</p>');

This is perfectly adequate for a few elements, but when you need to add hundreds or thousands of elements, inserting them individually can be too slow.

A better way is to build up all the intended elements into one big string and insert them simultaneously as a single unit. For each element, this prevents the overhead of the jQuery call and the various internal tests it performs:

var    elements = '';

// First build up a string containing all the elements.
for (var i = 0; i < 1000; i++) {
    elements += '<p>This is element ' + i + '</p>';

// They can now be inserted all at once.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, interactive tutorials, and more.

Start Free Trial

No credit card required