Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / Javascript

JavaScript Performance Tips

4.72/5 (11 votes)
23 Jul 2013CPOL3 min read 36.9K  
Some useful tips on JavaScript code performance

Introduction

In this tip, I have tried to capture the common design and coding mistakes JavaScript developers tend to make. The intended audience for this article is JavaScript beginners with a few years of programming experience.

Background

Over the years, I have observed how web based Enterprise/Consumer software is designed, developed and tested. One common trait in all of these applications is the usage of JavaScript. More often than not, developers either overlook or are ignorant about JavaScript performance. This is partly because these days, the machines are mostly high end and the browsers with their ever improving script engines have to some extent camouflaged the performance aspect. So developers are not penalized for writing bad JavaScript. Nevertheless if developers follow certain discipline while coding JavaScript, they'll definitely notice that their app will improve in terms of performance and maintainability.

Tips on Performance

  1. Always prefer the Single var pattern. JavaScript Engine hosts all the vars to the top of the function. So even if we declare our var at the bottom of the function, it doesn’t matter. Remember JS isn’t compiled into a binary! In the example below, both functions are the same but the second one is optimal.
  2. JavaScript
    function foo() {
        var c = 1;
        //lots of logic
        //and then
        var d = 0;
    var e;
    }
     
    function foo() {
        var c = 1, d = 0, e;
    
    }
  3. Do not use for-in loop to iterate over arrays. Use for loop instead. for-in loops should be used to iterate user defined object literals. The example below takes more time to execute in comparison with a simple for loop.
  4. JavaScript
    //Takes more time
    var i, b, c;
    for (i in c=[1,2,3]) {
        b = c[i];
        if(b === "x")
            DoSomething();
    }

    For-in loop iterates over every property, even the prototype! So in the example above, it loops through all properties of c.prototype and in case c.prototype has a property called ‘prop’, it also iterates over c.prototype.prop.prototype, etc. This clearly is not necessary if all we want is to loop through an array.

  5. Avoid returning undeclared variables from a function.
  6. JavaScript
    function foo(a, b) {
        r = a + b;
        return r; //creates a variable r in global scope!
    }
  7. Cache your objects whenever possible.
  8. JavaScript
    //Good
    for (var i = 0, x = p.length; i<x; i+=1) {
        
    }
    //Better
    for (var i = 0, x; x= p[i]; i += 1) {
     
    }

    Even when you use libraries like jQuery, YUI, MooTools, etc., ensure that you cache the selector. Remember DOM Traversal is costly!

    JavaScript
    function foo() {
        var d = $("#myDiv"), c = $("#myDiv:firstchild");
        //.....
        //Use d and c later whenever needed!
    }
  9. Return this from your initializer to facilitate chaining. In the below example, we are able to call doAjax on init because we induced chaining by returning this.
  10. JavaScript
    var MyApp = {};
    MyApp.Utilities = (function () {
      
        return {
            init: function (a,b,c) {
                //initialize your stuff
                return this;
            },
            doAjax: function() {
                
            }
        };
    })();
     
    MyApp.Utilities.init().doAjax();

    Note: If you have a constructor for your class, you don’t have to return this explicitly. Constructors always return this.

  11. Avoid nesting deep inside a function. Well, this applies to any programming language.
  12. JavaScript
    //Not recommended
    function successCbk(r) {
        if (r) {
            if (r.data) {
                if (r.data.myProp) {
    //Do something
                } else {
                    
                }
            }
        }
    }
     
    //Better!!
    function successCbk(r) {
        if (!r) return;
        if (!r.data) return;
        
        if (r.data.myProp) {
    //Do something
        } else {
     
        }
    }
  13. Avoid memory leaks and circular references in your closures. Developers typically tend to write the code below:
  14. JavaScript
    //Classic case for circular references
    function foo(e,d) {
        $(e).on("click", function() {
            //Do something with d
        });
    }

    The problem with the code above is that the click callback closure for the element e keeps a reference to both e and d even though it just uses d. Similarly, e also keeps a reference to the closure thus creating a circular reference. These functions will never be garbage collected. The trick is to break this chain!

    JavaScript
    //Break the cycle!
    function foo(e, d) {
        $(e).on("click", cbk(d));
    }
    
    function cbk (d) {
    } 

Parting Note

If you find this tip useful, please share it with the developer community. I haven't executed every line of code in this tip, so in case you find discrepancies, please comment on the post. I'll incorporate the changes as soon as possible.

Happy learning. :)

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)