📣Postmark has been acquired by ActiveCampaign
x

JavaScript optimization: Adding DOM elements to document

Scenario: you’re developing rich Web application and you need to load dynamic elements using AJAX and then add them to current document. For some reason you don’t want (or can’t) use fully generated HTML, and decided to fetch items in JavaScript array.

I know two classic ways to do so: create elements using document.createElement() method and concatenate HTML strings and assign result to parentElement.innerHTML property. Of course, you can combine both ways. Let’s examine these ways in detail.

Classic way (and in ideal world the best way) is to use DOM for element manipulations:

for (var i = 1; i < = 1000; i++) {
var li = document.createElement('li');
  li.appendChild(document.createTextNode('Element ' + i));
  el.appendChild(li);
}

I got 1403 ms in Internet Explorer 6 and 165 ms in Firefox 1.5. Not so bad, but what about creating DOM element from HTML code?

for (var i = 1; i < = 1000; i++) {
  var li = document.createElement('<li>Element ' + i + ')
  el.appendChild(li);
}

It works better in Internet Explorer (1134 ms), but does not work in Firefox at all. Weird! Of course, you can add try/catch block and create elements using first approach in catch block for Firefox. But I have a better solution.

Every DOM node has the attribute innerHTML which holds all child nodes as an HTML string.

el.innerHTML = '';
for (var i = 1; i < = 1000; i++) {
  el.innerHTML += '<li>Element ' + i + '';
}

Wow, 39757 ms in Internet Explorer and 41058 ms in Firefox! Cool result, right? It's because browser tried to render list while we updating and it takes such a long time. Little optimization:

var html = '';
for (var i = 1; i < = 1000; i++) {
  html += '<li>Element ' + i + '';
}
el.innerHTML = html;

Firefox shows great performance, 50 ms, but Internet Explorer still slow – 10994 ms. I found solution which works very fast in both browsers: to create array of HTML chunks, and the join them using empty string:

var html = [];
for (var i = 1; i < = 1000; i++) {
  html.push('<li>Element ');
  html.push(i);
  html.push('');
}
el.innerHTML = html.join('');

It’s fastest approach for Internet Explorer 6 – 407 ms, and very fast in Firefox – 47 ms. Why I’m not saying fastest in case of Firefox? I added another test to make in cleaner:

var html = '';
for (var i = 1; i < = 1000; i++) {
  html += '<li style="padding-left: ' + (i % 50) + '" id="item-' + i + '">Element ' + i + ' Column ' + (i % 50) + '';
}
el.innerHTML = html;

And second example:

var html = [];
for (var i = 1; i < = 1000; i++) {
  html.push('<li style="padding-left: ');
  html.push(i % 50);
  html.push('" id="item-');
  html.push(i);
  html.push('">Element ');
  html.push(i);
  html.push(' Column ');
  html.push(i % 50);
  html.push('');
}
el.innerHTML = html.join('');

84 ms for the first example and 110 ms for the second.

Here is results in table and diagram formats.

No Method Internet Explorer 6 Firefox 1.5
1 document.createElement() 1403 166
2 document.createElement() Full 1134 —
3 element.innerHTML 39757 41058
4 element.innerHTML Optimized 10994 50
5 element.innerHTML Join 400 47
6 element.innerHTML Optimized Large 28934 84
7 element.innerHTML Join Large 950 110
Adding DOM elements to document