Blog Post default image

Speed up JavaScript by making it execute exceedingly fast with these Google certified techniques

Ok everyone’s good friend David Walsh over at davidwalsh.name posted a link to a Google Talks presentation – Javascript and speed from back in 2009 in which they discuss some simple yet amazingly important JavaScript optimisation techniques. Ranging from Dom interaction and Scope , all the way through to Reflow. Now if your not sure what Reflow is I will explain that below, but put simple it is the name given when the browser has to redraw the page because user interaction or JavaScript has changed its geometry.

So here is what I’m going to cover in this post for you optimisation fanatics, with code examples of the good, the bad and the ugly!

  • Scope Management
  • Data Access
  • Loops
  • The DOM

Scope Management

As JavaScript developers we should all have a decent handle on what scope is, but managing the scope within our apps and functions is a little trickier. There is no real best practice solution for how to pass around variables, literals, arrays and properties in the language, and many developers will live by, “if it works, it works”. Well sure, but if your users perceive your web-site to be slow because of that attitude, you lose out big time. So here are a few key concepts when it comes to scope management to improve performance.

Key points

  • The further into the scope chain, the longer it will take to resolve identifiers
  • Local variables = fast!

1. The further into the scope chain, the longer it will take

When your functions are executed what is called an execution context is created, this execution context is intialised with a scope collection, the collection contains that functions scope members. Examples of this would be your function now has references to window and document.

Now if that seemed a little complicated, here are some simple slides to illustrate.

Scope chain for a typical function

scope context with local variables

Next the function will create what is called an activation object, which contains all your local variables and pushes them to the front of your context’s scope chain.

Scope chain for a function after activation object

scope context global

So when the function is executed and it comes across a variable a process called Identifier resolution starts. It will always starts by looking in the first spot in the scope chain, and will make its way down the scope chain until that variable is found.

So quite simply, if you find your variable in position 0. Excellent, that is the best possible outcome and the fastest.

Anything beyond position 0 requires extra processing and time to find, and every step you go down the scope chains adds to how long it takes. So the further down the scope chain the bigger the hit to your performance. Hence why we try not to use Global variables, because they will always be in the last spot of the scope chain.

2. Local Variables = fast!

Local variables are extremely fast because they require only one step in the scope chain to find. Simple as that, and below are two pieces of code to demonstrate local variable importance.

A typical function

{code type=php}
function (items) {
var divs = document.getElementsByTagName(“div”);
var images = document.getElementsByTagName(“img”);
var button = document.getElementById(“save-btn”);
for (var i=0; i < items.length; i++) { process(items[i], divs[i], images[i]); } } {/code}

Same function but faster

{code type=php}
function (items) {
var doc = document;
var divs = doc.getElementsByTagName(“div”);
var images = doc.getElementsByTagName(“img”);
var button = doc.getElementById(“save-btn”);
for (var i=0; i < items.length; i++) { process(items[i], divs[i], images[i]); } } {/code} You will see a big difference when writing functions like this because instead of three global lookups, you now have one!

Pages: 1 2 3 4

2 Comments

  1. Very informative article. I guess it’s simple tips like this that make the difference between light and heavy code. Do these techniques apply to PHP too?

  2. CraigW says:

    I had a function which was taking over 37000ms to execute on IE6 (our company still insist on using IE6) and even 24,000ms in IE8 – Firefox executed the same function in 150ms.

    I discovered the cause – I was using a for – in to iterate around an array and it seems that IE is incapable of optimising for – in loops. I changed the code so it was using a for loop:

    OLD Code

    for (elementNo in myArray)
    {
    }

    NEW Code

    var totalElements = myArray.length;
    for (var elementNo = 0; elementNo < totalElements; elementNo ++)
    {
    }

    This reduced the IE6 time to 700ms (Firefox was 20ms faster).

Post a Comment