jQuery / Javascript Optimization

About the Javascript language

Javascript is an interpreted language. The opposite of interpreted code is compiled code. Languages like C++, ObjectiveC, Java and .NET are compiled to some degree or another. This means that every time Javascript code is executed, the web browser has to parse your source code line by line and run the appropriate low level commands. For compiled programs, your code is turned into low level machine code by a compiler and a binary is produced. Interpreted code has much more security checks (to keep you from crashing or hacking the browser) and more overhead than compiled code, so compiled code will always be orders of magnitude faster than interpreted code.

Javascript of course relies on compiled code to carry out many of its global functions – things that are provided by the browser or are built in parts of the language. So for example, when you call something like:

document.getElementById("MyElement")

The actual code that searches the document for that element is code that is compiled into the browser (not javascript). Or when you call somearray.reverse() that code is optimized, compiled code. It will always be faster to call a built in function than to write similar code in javascript. Eg.

var somearray = [ 'a', 'b', 'c'];
var reversedArray = [ ];
for(var i=0; i<somearray.length; i++)
{
	reversedArray.push( somearray.pop() );
}

Always slower than somearray.reverse();

When to use jQuery?

jQuery is a great help in making more complicated Javascript operations simpler and in writing browser independent code. There’s not really a strong reason why you would not want to use jQuery. The cons of jQuery are that it adds extra http requests to the page download and extra k weight to the page.

You may ask, is it faster to do

document.getElementById("MyElement")

than

$(“#MyElement”)

The answer is yes, it probably is faster since it has less overhead. Does it make a noticeable difference? Probably not. I would personally rather use jQuery and have code that is easier to read, since most things take less code to do in jQuery. jQuery also gives you a much more powerful set of features out of the box, which saves time and lets people do more. If you are in a scenario where you need to update hundreds of id’s and you are hitting a performance bottleneck, then by all means re-write those lines using the regular Javascript. Otherwise, don’t worry about it.

About Selectors

Everytime you do a selector in jQuery, jQuery searches through the DOM to find any elements that match your selector string. Some types of selectors will be slower than others; doing a selector on a class or ID will be quick, since these will use the built in Javascript functions for retrieving classed and id’d elements. Other types of selectors could be very slow and cause jQuery to need to search through large numbers of DOM elements. The best practice is to a) Keep your selectors as simple as they can be b) Use classes and id’s to address elements whenever possible as opposed to relying on nested selectors (eg: if ($(“body div .someclass a”)), and c) Save selector results when you are going to make multiple calls on a selector.

Save selector results

With jQuery, it’s very common to need to do several operations on the same DOM elements. Such as:

if ($("#filter_options ul").css("display") == "none") {
	$('#filter_options ul').show();
	…
}

Doing something like this saves jQuery from needing to look up the same thing twice.

var dropdownObj = $("#filter_options ul");
if (dropdownObj.css("display") == "none") {
	dropdownObj.show();
	...
}

‘Property depth’ – reduce number of variable lookups

Let’s say you are referencing properties of some object:

player[i].data.position.x = 55;
player[i].data.position.y = 55;
player[i].data.position.angle = 0;

It takes less operations to do it this way:

var pos = player[i].data.position;
pos.x = 55;
pos.y = 55;
pos.angle = 0;

This is because we save ourselves from having to look up the index ‘i’ in player and having to look up the property data and the property position each time. Each one of those operations probably entails searching in an array for a named variable in the javascript runtime.

General optimization techniques

Algorithmic efficiency

A way of gauging how slow an algorithm will be is to figure out how many elements need to be processed.
For example, consider the following two situations:

for(var i=0; i<A; i++)
{
	for(var j=0; j<B; j++)
	{
	}
}

Or:

for(var i=0; i<A; i++)
{
}

for(var j=0; j<B; j++)
{
}

In the first scenario, the inner loop executes every time the outer loop executes, so we end up looping A x B times. In the second scenario, we are looping A times then B times. So it’s A + B loops. Scenario 1 should be slower (assuming both accomplish the same result).

This brings us to another important point. Optimize your innermost loops (as in scenario 1). Those loops get executed many times, so even removing one or two lines of code from those will see big benefits. If you can move some code outside of the loop (such as initializing or declaring a variable), it would be faster than doing it on every pass.

Algorithmic efficiency is usually expressed using Big-O notation (see here). Typical front end code is O(1) or O(N). You won’t see some of the other values unless you start writing search algorithms or factoring numbers.

Optimize algorithms first, worry about specific line by line optimizations last

Since javascript is interpreted, there is already lots of overhead on every line of code. Work on reducing the complexity and number of lines in your script first before worrying about whether it’s faster to do:

for(var i=0; i<num; i++) 
{
}

Or

while(i--)
{
}

The second one is faster BTW. ;)

Recognize slow operations / slow rendering

People criticize Flash for being a CPU hog. Javascript animation is just as slow if not slower for doing less stuff. If your fancy glowing buttons are too CPU intensive, they may not be usable on a mobile device and will need to be removed on the mobile site (why is Javascript better than Flash again? ;) ) It’s important to check your OS Activity Monitor (Task Manager on Windows) to check the CPU usage of the browser. If you’re pushing 50% CPU or higher, then chances are good that what you are doing won’t work well on mobile. Some things that are known to be slow when animated are drop shadows, blurs and glows. Static drop shadows may be fine, since most browsers render these once and cache the results in memory. Animating it causes it to be redrawn on every frame.

Also, if you have a page with 50 buttons that all have rollovers, be sure to test what happens when people rollover several things simultaneously. It’s easy to forget that animations in jQuery work on a queue system, so they can stack up or have unintended consequences when triggered in rapid succession. It may be necessary to stop existing animations before adding new ones (see clearQueue() ).

Slow operations

Some types of functions, even though they are calling native code are just slow. An example of this is the trig functions – Math.sin, Math.cos, Math.tan, etc. If you need to make a lot of calls to sin() and cos(), you can try using a Lookup table (essentially caching the results).

In general, not all operations are created equal. Division is slower than addition or subtraction. Binary operations (&, |, ^, etc) are the fastest of all. Sometimes a division can be rewritten as multiplication (eg: / 2.0 can be re-written as * 0.5).

Any operation that accesses storage, hardware or the network is going to be far slower than pure math or other simple operations that occur entirely on the CPU. In order of slowness: Network > Hard Drive > RAM > basic CPU operations.

These types of things are less of a concern in Javascript, but it’s good to know.

The sin of Premature Optimization

Some people take optimization to the extreme and try to optimize everything while they are writing it. This leads to cryptic, unreadable code and is a waste of your time. Most programs in need of optimization have a limited number of ‘bottlenecks’ where slowdowns occur. Optimizing other areas will usually be unnoticeable to the end user and will yield only small gains. Write clean code first, identify your bottlenecks, then re-write or optimize those sections as needed. In today’s world, it’s common for other developers to need to read your code, so it’s more important for code to be readable and easily understood than it is for every line to be optimized.

Leave a Reply

Close Modal

Contact Archer

Close Modal

We know you're still using an older version of Internet Explorer. Do you know how much mind-blowing stuff you're missing because of this?

Save yourself. Upgrade now.
We'll help you...