Performance Tip #3: Setting Styles

A common task to do in JavaScript is to change the appearance of elements dynamically.

There’s a couple of ways of doing that:

1. Setting style properties in the DOM

 divTest.style.backgroundColor = "red";
divTest.style.fontWeight = "bold";

2. Setting the style property to a CSS string

 divTest.style.cssText = "background-color: red; font-weight: bold; margin: 0px 0px 0px 0px;";

3. Setting a CSS class name

 divTest.className = "newStyle";

 newStyle{ background-color: red; font-weight: bold; margin: 0px 0px 0px 0px; } 

Whichever way a style for an element happens there is a couple of things that need to happen:

  1. Dispatch to the DOM
  2. Style calculation
  3. Layout calculation
  4. Rendering

As JavaScript (and to some extent the browser) is single threaded the first three steps need to happen before the next JavaScript statement can execute. For example if you set the color attribute for the body you would expect that any children who didn’t specify a fontColor would now return the value just set on the body. E.g.:

 var divTest = document.getElementById("divTest"); 
alert(divTest.currentStyle["color"]); // alert's #000000 (default)
document.body.style.color = "blue";
alert(divTest.currentStyle["color"]); // alert's blue

That works in IE in other browsers you will need to use the standard getComputedStyle. As the same thing happens for attributes involving layout it’s reasonable to assume that layout is also calculated before the completion of the JavaScript statement.

What doesn’t happen is the actual rendering of the updated page. This frequently causes developers problems. For example if you tried to show a “please wait” dialog while some long running synchronous operation completes you’d find that the dialog doesn’t display and the page isn’t updated. This is true in IE but other browsers have different behavior.

With this knowledge we can start to time and measure the different ways of updating the page. To do it fairly we need to only consider the different approaches but also the complexity of the page.

Trying the three approaches on a couple of pages gets some interesting results:

(100 iterations) Style DOM Style String Class Name
about:blank 25 ms 44 ms 33 ms
google.com 26 ms 69 ms 188 ms
cnn.com 47 ms 193 ms 10,651 ms