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:
- Dispatch to the DOM
- Style calculation
- Layout calculation
- 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 |