HTML5 Zone is brought to you in partnership with:

I am a software engineer and blogger. I try to post to my blog whenever I have free time. My passion is to learn new things each day. Yusuf is a DZone MVB and is not an employee of DZone and has posted 12 posts at DZone. You can read more from them at their website. View Full User Profile

Faster Javascript

10.01.2012
| 3433 views |
  • submit to reddit

JavaScript is a very important language for now and the future. Nowadays, there is no pages that do not include some JavaScript code in it. Moreover, code written in JavaScript increases day by day. The more JavaScript code we have in our web pages, the worse performance we observe. This occurs because of some tricks in JavaScript as a language. In this post, I will try to explain what the problems are and what possible solutions we can have. Before going into detail, let me explain what I am going to talk about. The first one will be about scoping, second will be libraries and last one is DOM manipulation and properties.

JavaScript is a language that uses dynamic scoping. In each function, we have default scope variables (window, navigator, document) that are pushed onto our stack. After those, each local variable is pushed onto stack with a separate block. Using local scope variables is faster than the global scope variables. At that point, we prefer using local variables. At least we can retrieve global variable and set it to a local variable. Note that, when we are creating a new variable, we should always use “var” since if we do not, they will have a global scope instead of local scope. Here is an example.

function begin(){
    document.getElementById("div1");
    document.getElementById("div2");
    document.getElementById("div3");
}
function begin(){
    var doc = document;
    doc.getElementById("div1");
    doc.getElementById("div2");
    doc.getElementById("div3");
}

Furthermore, JavaScript provides closures where we can pass a variable to another function that is dynamically created. The variable we pass into other function comes from another scope so this will result in a performance issue. Therefore, we should set it to a local variable. Let us see another example for closures.

function addClick(){
    var div = document.getElementById("div1");
    div.addEventListener("click",function(){
        div.style.marginTop = "32px";
        div.style.color = "blue";
    },false);
}
function addClick(){
    var div = document.getElementById("div1");
    div.addEventListener("click",function(){
        var localDiv = div;
        localDiv.style.marginTop = "32px";
        localDiv.style.color = "blue";
    },false);
}

Our second point is using JavaScript Libraries which are very helpful most of the time. On the other hand, when you need performance, you may fail if you are using JavaScript Library. Let me explain by an example. We generally loop through each or foreach defined in most of the popular JavaScript libraries. However, this usage is very bad comparing it to a regular loop since in each iteration you create a function and destroy it afterwards. That means you create a local stack, pass variables into that and destroy it after execution. What is more, most of the JavaScript libraries creates their native object which are heavier than regular DOM elements. They include lots of functions and variables belong to library and you use just one or two of them. Consequently, you have waste of functions or variables. If you want faster code, you may use less JavaScript library help.

Last but very important is DOM manipulation and properties. In retrieving properties, we use generally things like element.style.color which has a depth of two; meaning you pass through two variables to reach what you are looking for. The more depth you have in your variable, the slower your program will execute. As we have discussed in previous examples, you should retrieve the element and store it to a local variable. Moreover, if you are dealing with DOM, those retrieval times are much more slower. So, I suggest you to use local variables as often as you can.

When you load the page, all collections are stored in an HTML Collection object which understands all the updates on DOM manipulation. As a result, we have a very slow access(because it is fat) when we are dealing with this object which is everywhere. For instance, when we call getElementsByTagName, it returns us an HTML Collection. Using these collection variables is so slow and should be avoided. Let see this by an example.

function updateDivs(){
    var divs = document.getElementsByTagName("div");
    for(var i=0;i<divs.length;i++){
    // instead we can use
    // for(var i=0, length=divs.length;i<length;i++)
         update(divs[i]);         
    }
}

As you can observe, HTML is dynamic i.e. when you change any element, it updates itself automatically but costly. When we create and append an element, we lose performance because browser calculates new position, size and etc. of div each time. Instead, we can use HTML fragments and append what we have created like a batch operation. Here is an example.

function appendDivs(element){
    for(var i=0;i<10;i++){
        var div = document.createElement("div");
        element.appendChild(div);           
    }
}
function appendDivs(element){
    var fragment = document.createDocumentFragment();
    for(var i=0;i<10;i++){
        var div = document.createElement("div");
        fragment.appendChild(div);           
    }
    element.appendChild(fragment);
}

Throughout my journey, I have tried to explain some basic key points to have faster codes. The basic idea generally is to use local variables, use less Library support and do DOM manipulation in a right way.

 

 

Published at DZone with permission of Yusuf Aytaş, author and DZone MVB. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)