Getting information on JavaScript performance really is like finding a female programmer. (No punchline to protect myself from the females.) So excuse me if you’ve heard some of this before, but for those JS Perf virgins out there here’s some of the notes I’ve compiled.

Caching

In Javascript you can copy references to Arrays, Functions, Dom elements, anything and once you have that element cached in a local context, you avoid some icky lookups. having lots of periods in a reference (sys.ajax.enums.serverparsed.transformers.optimusprime) creates a lot of object lookups that will hit you on every lookup. In the grand scheme of things, this isn’t that big of a problem, often you won’t be doing any operation often enough that the milliseconds this call would save in any particular call, but something to keep in mind.

Don’t hit the Dom

The last big script application I wrote was an excel like application, so on some occasions there were 450 x 60 (27,000) cells on the page, which I would have to iterate over and perform some operation. In this application the number one performance gain was to cache the properties of each cell and determine if any operations are necessary based on that cached version. Avoiding .innerHTML for reading, not using getAttribute, setAttribute for storing information about the cell, and don’t store references to script manager objects on the dom object.

Prototype’s

The difference here is memory, you only need one instance of a function, unless for some reason you construct the string of the function, but for the most part, if you use prototypes you’ll only get the one instance of the function instead of an instance for each instance. Got it?

Loop backwards and Duffs Device

Put this in the “Almost to small to care” folder. Looping backwards for some reason, gets you a few milliseconds on your loop. Duffs device is a method of executing the same code while not needing to loop quite as much. Its worth it in loops of several thousand iterations, but overall it hurts readability and bloats the code, so look for gains elsewhere.

switch (count % 8)  /* count > 0 assumed */ { case 0:        do {  *to = *from++;

case 7:              *to = *from++;

case 6:              *to = *from++;

case 5:              *to = *from++;

case 4:              *to = *from++;

case 3:              *to = *from++;

case 2:              *to = *from++;

case 1:              *to = *from++;

}  while ((count -= 8) > 0);

}

Manager Objects

In this aforementioned excel like application, I adhered to an object oriented methodology, which turned out to be neurotic. This application ended up having thousands of objects in memory just to manage each cell. It would have been much smarter to have one object that manages all these thousands of cells. This also allows for removing the reference on the dom object to their individual script object instance. Instead I would put just a string identifier on the object which I would use to get from a hash.

var scope

This should be in the obvious section, but if you don’t use var when declaring your variables, the JS engine searches up the chain looking for a property to set, and if it doesn’t find it, then it uses a global variable on the window. At which point references to the variable become global property lookups.

Leaky Memory

Memory holes are causes by circular references that confuse the garbage collector. Namely, DomElement -> Script Object -> Dom Element. Avoid at all costs, if you need, save a string id on the Dom element, and use that to retrieve the script object when you need it.

function Obj(xEl) {

 this.Ref = xEl;

}//--- Memory hole in the making

document.getElementById("el").xScript = new Obj(document.getElementById("el"));

eval()

Everyone knows this is already a performance hog and you shouldn’t use it. Not sure why? Well, when the page loads it goes through all the Script on the page, parses it and loads it then shuts down so the page can go about the rest of its business. When you eval, you start this loading engine again, and this is as heavy a process as it sounds. While not as evil, the new Function(“”) constructor is just as evil, it uses an eval to construct a function from a string value. Never eval to get a variable reference, you can use the bracket structure to pass the name of the variable to its parent object

window["location"]["href"] = "http://www.blackbeltcoder.net/"

If you can think of any others, please post a comment and we’ll get those added. I’ll probably add a part 2 as I remember a few other tricks.

2 comments

2 Responses to “Javascript performance notes”

  1. guru Says:

    thanks !!

  2. Kris Gray Says:

    Your welcome.

    🙂

Leave a Reply