Friday, November 20th, 2009
Full Frontal ’09: Jake Archibald on Performance Optimisation
<p>Jake explains no-one likes waiting, and people are multi-threaded (except when they have to sneeze). Yet, we're stuck with a single-threaded language for the most part; and we still face the legacy of a DOM standard from another era (DOM Level 1 - 1997). This talk provides some optimisation tips, backed by Jake's cross-browser experiments.Jake's slides and research are online.
Optimise Where it Matters
Jake explains the importance of speeding things up where it really matters.
Doug Crockford has pointed out that in Javascript, bitwise operations aren't close to the hardware, which stands in contrast to other languages. In fact, if you look at it, bitwise operations can still be faster than alternative operations; Jake shows an example where bitwise parsing of hex codes is faster than bitwise. The question is, how much faster? In many cases, such as this example, your energy is better spent on optimising big things.
Avoid eval() Where Possible
Jake says avoid eval() where possible. Thinking about what functions eval, here's a brain teaser: what will the following output?
-
-
var msg = "spatchcock";
-
function doStuff() {
-
alert(msg);
-
if (false) {
-
var msg="spotted dick";
-
}
-
}
-
doStuff();
-
Wait for it ... the answer is "undefined". Javascript does look ahead and create space for the local variable. So during the running of the function, there's no need to allocate space for the variable and the browser can optimise for that, but if you use "eval", the optimisation goes away. So avoid eval().
Prefer innerHTML to DOM
Jake shows a comparison of innerHTML versus DOM Level 1. In IE, DOM manipulation is much slower, because of the sync process between the two. The differential gets even worse when creating elements. Webkit has optimised sync between HTML and DOM, hence less difference, so it's not as bad, but create example is still slower with DOM. So from a performance perspective, best practice is construct the HTML and use innerHTML.
Selectors
It's educational to look at the implementation of selector libraries. Jake shows a comparison - IE7 is vastly more slow in this case. It doesn't support getElementsByClassName, querySelectorAll, evaluate; and it does support getElementById, but that's not used by sizzle for this query. So getElementsByTagName is all that's left; and if you knew that, and the implications, you could have made the query much faster.
Benchmarking
Pretty simple.
-
-
var duration;
-
start = new Date()
-
thingToTest();
-
duration = new Date() - start;
-
However, timing isn't so accurate, so stick it in a function and run it many times.
Too easy ... so go benchmark and report your findings.
Related Content:











Sad to see, that innerHTML is still faster. Sure, often its more easier. But DOM is safer to create valid & working content in webapps.
what an odd bit of example code, heh.
in the first code example, I think there should actually be a call to doStuff() at the end
Really interesting articles. There’s been a change for the worse in the writing style recently however – it looks like the notes are being taken down as the speakers are talking, which is fine if that’s the case. Will it return to normal for other articles though? As an example, a paragraph such as
“Doug Crockford has pointed out that in Javascript, bitwise operations aren’t close to the hardware, which stands in contrast to other languages. In fact, if you look at it, bitwise operations can still be faster than alternative operations; Jake shows an example where bitwise parsing of hex codes is faster than bitwise. The question is, how much faster. In many cases, such as this example, you’re energy is better spent on optimising big things.”
is actually quite hard to understand and it’s not just the fact that “you’re” should be “your” and there’s a question mark missing. Perhaps a quick post-edit would be some help?
@okohll, thanks I’ve fixed that. The notes from Full Frontal today were indeed being live blogged under a less-than-ideal 3G (in theory only) connection, which made post-editing something of a challenge at times.
I think DOM test results would be more interesting if there was only one execution of “container.appendChild(bufferDiv);” as innerHTML do (container.innerHTML = str;).
@checkca
Added a couple of variations on the DOM level 1 methods, including one that only does 1 append to container. It’s faster in Firefox but slower in IE, but the differences are minor.
Very interesting to run the tests before & after opening the web inspector in webkit.
Oops, forgot to add a url for those: http://www.jakearchibald.co.uk/jsperformance/creatingelements/
@jaffathecake
When I use document.createElement(‘div’) instead of document.createDocumentFragment(), it gives me the best results on Chrome. I know it’s not exactly the same test as I add one more container DIV but it’s quite interesting.
3725ms – Dom Level 1 Method with Div Buffer
6834ms – Dom Level 1 Method with DocumentFragment
Have you opened the web inspector while you run that test? I only get figures like those if I’ve opened the inspector (which slows down the page and skews results).
Without web inspector:
~350ms – Dom Level 1 Method with DocumentFragment
~350ms – Dom Level 1 Method with div container
With web inspector open:
~1300ms – Dom Level 1 Method with DocumentFragment
~800ms – Dom Level 1 Method with div container
(results fluctuate wildly for this test on chrome, so the above is approxomate)
It’s weird… My Chrome (4.0.249.4) doesn’t have the same behaviour. When I close Chrome and reopens it without opening Web Inspector, I get those results :
div container ~= 800ms
doc fragment ~= 1400ms
With FireFox without firebug active, I get :
div container ~= 2500ms
doc fragment ~= 3400ms
IE8 takes ~= 5400ms (and ~= 1500ms with innerHTML), I hope MS will fix that in IE9 :p.
I imagine Chrome 4 is running with significant amounts of debug code enabled. My results are from Chrome 3.
Very interesting. I can’t find any audio to accompany the slides. Is it published anywhere?