JavaScript Best Practices: Performance – Be Scope-Aware

Excerpted from chapter 20 "Best Practices" of the Wrox book Professional JavaScript for Web Developers, 2nd Edition

By Nicholas C Zakas

Chapter 4 discussed the concept of scopes in JavaScript and how the scope chain works. As the number of scopes in the scope chain increases, so does the amount of time to access variables outside of the current scope. It is always slower to access a global variable than it is to access a local variable because the scope chain must be traversed. Anything you can do to decrease the amount of time spent traversing the scope chain will increase overall script performance.

Avoid Global Lookups

Perhaps the most important thing you can do to improve the performance of your scripts is to be wary of global lookups. Global variables and functions are always more expensive to use than local ones because they involve a scope chain lookup. Consider the following function:

javascript Code:
function updateUI(){
   
var imgs = document.getElementsByTagName("img");
   
for(var i=0, len=imgs.length; i < len; i++){
        imgs
[i].title = document.title + " image " + i;
   
}
 
   
var msg = document.getElementById("msg");
    msg.
innerHTML = "Update complete.";
}
 
This function may look perfectly fine, but it has three references to the global document object. If there are a large number of images on the page, the document reference in the for  loop could get executed dozens or hundreds of times, each time requiring a scope chain lookup. By creating a local variable that points to the document object, you can increase the performance of this function by limiting the number of global lookups to just one:
 
javascript Code:
function updateUI(){
   
var doc = document;
   
var imgs = doc.getElementsByTagName("img");
   
for(var i=0, len=imgs.length; i < len; i++){
        imgs
[i].title = doc.title + " image " + i;
   
}
 
   
var msg = doc.getElementById("msg");
    msg.
innerHTML = "Update complete.";
}
 
Here, the document object is first stored in the local doc variable. The doc variable is then used in place of document throughout the rest of the code. There’s only one global lookup in this function, compared to the previous version, ensuring that it will run faster. A good rule of thumb is to store any global object that is used more than once in a function as a local variable. 
 
Avoid the with Statement

The with statement should be avoided where performance is important. Similar to functions, the with statement creates its own scope and therefore increases the length of the scope chain for code executed within it. Code executed within a with statement is guaranteed to run slower than code executing outside, because of the extra steps in the scope chain lookup.  It is rare that the with statement is required, as it is mostly used to eliminate extra characters. In most cases, a local variable can be used to accomplish the same thing without introducing a new scope. Here is an example:
 
javascript Code:
function updateBody(){
   
with(document.body){
       
alert(tagName);
        innerHTML =
"Hello world!";
   
}
}
 
This code uses a with statement to use document.body  more easily. The same effect can be achieved by using a local variable, as follows:
 
javascript Code:
function updateBody(){
   
var body = document.body
   
alert(body.tagName);
    body.
innerHTML = "Hello world!";
}
 
Although this code is slightly longer, it reads better than the withstatement, ensuring that you know the object to which tagName and innerHTML belong. This code also saves global lookups by storing document.body in a local variable.
Tags:

Comments

Leave a Reply

What is 9 + 11 ?
Please leave these two fields as-is:
IMPORTANT! To be able to proceed, you need to solve the following simple math (so we know that you are a human) :-)