April 19, 2008, 11:11 pm · 0 comments · Filed under: JavaScript
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.
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.
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
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
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?
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 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.
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
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
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.
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('');
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);
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);
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!