innerHTML versus the DOM: Can’t we all just get along?

April 19, 2008, 11:11 pm · 0 comments · Filed under: JavaScript

Having tested the relative speed of innerHTML versus DOM node replacement myself, I read with interest When innerHTML isn’t Fast Enough. I have put together a test of my previous 2 techniques plus one inspired by that article.

andrew.hedges.name



Can your web browser do this?

You’ll never get rich digging a ditch, nor building Dashboard widgets.

A Kryptonite™ lock can be defeated in 11 seconds, but you still lock your bike, right?

Gaining Twitter followers is a little like losing weight. You have to try.

Over or under? It’s the age-old question when it comes to the orientation of toilet paper rolls.

Subscribe


Meta Me

I am a web developer, recently returned to the States after 3 years in New Zealand. I’m into my family, photography and frisbee sports.

Blip.fm Digg Facebook LinkedIn Stack Overflow Twitter Zooomr

Nothing will benefit human health and increase chances for survival of life on earth as much as the evolution to a vegetarian diet.
Albert Einstein


Topics

Apple · AppleScript · Business · Coda · CSS · Dashboard · Design · Google · InSTEDD · JavaScript · jQuery · Life · Marketing · Music · New Mexico · New Zealand · Open Source Software · Photography · PHP · Politics · Ruby on Rails · Scree · Subversion (SVN) · Twitter · Usability · Web Development · Widgets


Archives


Most Popular

CSS Fast Nav: Because (perception of) speed matters! · Personal Branding for Introverts · Stupid WebKit Tricks · Add an interactive legend to a MarkerManager managed Google Map · Dude. Mikeyy can’t even spell his own name. · Dashboard Widgets for Fun and Profit · Animating your iPhone web application · How-to recover from checksum mismatch errors in SVN · Why Apple can afford to charge so little for Snow Leopard · When is a global variable not a variable?


Most Recent

CSS Fast Nav: Because (perception of) speed matters! · When is a global variable not a variable? · Our misguided culture of cool · InSTEDD: Open Source Software that saves lives · Add an interactive legend to a MarkerManager managed Google Map · Personal Branding for Introverts · Moments of Rangitoto · Some Twitter conventions · Why Apple can afford to charge so little for Snow Leopard · Stupid WebKit Tricks


Twitshirt

Twitshirt is a tweet on a shirt. Buy the one below or check out my most recent tweets.

Is it fair to call "rain" a pet peeve?

See a random Twitshirt-worthy tweet.


Friends

80/20 · 90 Seven Design · Alyson Hurt · Andrew Nimick · Apps & Hats · Ben Young · Brian Arnold · Brian Warren · Carl Bolter · Chris Burgess · Christine Morris · Cristina Stoian · Daniel Lyons · Daniel Schwartz · David Hedges · Hamish Campbell · Jochen Daum · John Visser · Joseph McLaughlin · Joshua Sallach · Julian Pistorius · Justine Sanderson · Kalena Jordan · Katie Graham · Kelly Green · Kevin Potis · Mark Bixby · Matt Henry · Method Arts · Morgan Pyne · Peter Michaux · Philip Tellis · Piers Harding · Rebecca Murphey · Reid Givens · Rey Bango · Rhett Anderson · Richard Paul · Rob Pongsajapan · Robin Taylor · Ryan Park · Shaun Lee · Simon Young · Su Yin Khoo · Toni Barrett · Vaughan Rowsell · Vincent Thomé · Voom Studio


Recommended Books on
Web Development

My bias is for references over “cookbooks.” I want to know all of my options, not just one way to do something. Show me the why as well as the how and I am happy.

JavaScript: The Good Parts · Object-Oriented JavaScript: Create scalable, reusable high-quality JavaScript applications and libraries · JavaScript: The Definitive Guide · Designing with Web Standards · CSS: The Definitive Guide · Prioritizing Web Usability · The Elements of User Experience · Web ReDesign: Workflow that Works · Don't Make Me Think: A Common Sense Approach to Web Usability


Contact Info

Contact info for Andrew Hedges


I’ve hosted this website with pair Networks since 1997. They rock.

This blog is powered by…software I wrote.

Feeling generous? Knock yourself out!

Each of the buttons below writes the phrase Chubby bunny 10,000 times to the container div, clears the content, then does it again. What I’m trying to test here is the effect of the different ways of clearing out the DOM nodes from the container. Code and discussion follows.

innerHTML

This technique is the simplest and, probably, the most common on the web today. The following code builds up a long string of HTML, dumps it into the innerHTML attribute of the container div, then sets the content back to an empty string. Rinse, and repeat.

// Start 1st pass
innerHTML  = [];
iterations = iters + 1;
while (--iterations > 0) {
  innerHTML[innerHTML.length] = htmlDiv;
}
resultDiv.innerHTML = innerHTML.join('');
resultDiv.innerHTML = '';

// Start 2nd pass
innerHTML  = [];
iterations = iters + 1;
while (--iterations > 0) {
  innerHTML[innerHTML.length] = htmlDiv;
}
resultDiv.innerHTML = innerHTML.join('');

DOM replace

The following code builds up a document fragment by appending div nodes to it. The fragment is then appended to the container, a new fragment is built up, then the nodes are swapped out in one step.

// Start 1st pass
container  = document.createDocumentFragment();
iterations = iters;
container.appendChild(nodeDiv);
while (--iterations > 0) {
  container.appendChild(container.firstChild.cloneNode(true));
}
resultDiv.appendChild(container);

// Start 2nd pass
cloneDiv    = resultDiv.cloneNode(false);
cloneDiv.id = 'result-domreplace';
container   = document.createDocumentFragment();
iterations  = iters;
container.appendChild(nodeDiv);
while (--iterations > 0) {
  container.appendChild(container.firstChild.cloneNode(true));
}
resultDiv.parentNode.replaceChild(cloneDiv, resultDiv);
cloneDiv.appendChild(container);

innerHTML + DOM replace

The following code combines inserting a string of HTML via the innerHTML attribute with the one-step swapping goodness of the DOM replace code.

// Start 1st pass
innerHTML  = [];
iterations = iters + 1;
while (--iterations > 0) {
  innerHTML[innerHTML.length] = htmlDiv;
}
resultDiv.innerHTML = innerHTML.join('');

// Start 2nd pass
container  = resultDiv.cloneNode(false);
innerHTML  = [];
iterations = iters + 1;
while (--iterations > 0) {
  innerHTML[innerHTML.length] = htmlDiv;
}
container.innerHTML = innerHTML.join('');
resultDiv.parentNode.replaceChild(container, resultDiv);

View full source code

In theory, the last technique should be the fastest because the bottleneck with innerHTML is in removing the nodes by setting its value to an empty string. By building up a document fragment then swapping it out with the parentNode.replaceChild technique, we avoid using innerHTML to tear down the DOM.

In my testing, however, results were all over the shop. In Firefox, the results were as I expected: innerHTML was slowest, DOM replacement faster, and the combo technique fastest. In Internet Explorer, innerHTML was the fastest, the combo technique nearly as fast, and straight DOM manipulation nearly an order of magnitude slower. In Safari 3, I found no significant difference among the 3 techniques.

The following numbers are averages of 5 runs of each technique in the various browsers, expressed in milliseconds.


innerHTML DOM replacement innerHTML + DOM
Safari 3 109 104 96
Safari 2 489 849 457
Firefox 3b4 1588 1030 523
Firefox 2 1386 1019 401
IE 8b1 900 2131 844
IE 7 290 1275 475
IE 6 339 1880 373
Opera 9.27 266 847 675

From the above, it looks like the biggest advantage of the combo technique is its consistency across browsers. While straight innerHTML is faster on some browsers and straight DOM manipulation is faster on others, combining the 2 techniques yields decent performance across browsers.

Update: I added numbers for Safari 2, IE 8b1 and Opera 9.27 to the list above. My conclusion still appears to hold.


Short URL to this article:
Tweet this article!


Comments close automatically after 90 days.
Still have something to say? Drop me a line!

Possibly related posts