DOM creation createElement vs innerHTML vs jQuery vs underscore.js Template

JavaScript performance comparison

Revision 2 of this test case created by

Preparation code

<script type="text/javascript" src="http://code.jquery.com/jquery-1.7.2.min.js"></script>
<script type="text/javascript" src="http://ajax.cdnjs.com/ajax/libs/json2/20110223/json2.js"></script>
<script type="text/javascript" src="http://documentcloud.github.com/underscore/underscore-min.js"></script>

<div id="dom-creation" style="display: none;">container for creating nodes with innerHTML</div>

<script id="template" type="text/html">
    <table>
        <% $.each(models, function(i, model) { %>
            <tr>
                <td><%- model.prop1 %></td>
                <td><%- model.prop2 %></td>
                <td><%- model.prop3 %></td>
                <td><%- model.prop4 %></td>
                <td><%- model.prop5 %></td>
            </tr>
        <% }); %>
    </table>
</script>

<script id="template-no-with" type="text/html">
    <table>
        <% $.each(obj.models, function(i, model) { %>
            <tr>
                <td><%- model.prop1 %></td>
                <td><%- model.prop2 %></td>
                <td><%- model.prop3 %></td>
                <td><%- model.prop4 %></td>
                <td><%- model.prop5 %></td>
            </tr>
        <% }); %>
    </table>
</script>

      
<script>
Benchmark.prototype.setup = function() {
    _.templateNoWith = function(str, data) {
      var c  = _.templateSettings;
      var tmpl = 'var __p=[],print=function(){__p.push.apply(__p,arguments);};' +
        '__p.push(\'' +
        str.replace(/\\/g, '\\\\')
           .replace(/'/g, "\\'")
           .replace(c.escape || noMatch, function(match, code) {
             return "',_.escape(" + unescape(code) + "),'";
           })
           .replace(c.interpolate || noMatch, function(match, code) {
             return "'," + unescape(code) + ",'";
           })
           .replace(c.evaluate || noMatch, function(match, code) {
             return "');" + unescape(code).replace(/[\r\n\t]/g, ' ') + ";__p.push('";
           })
           .replace(/\r/g, '\\r')
           .replace(/\n/g, '\\n')
           .replace(/\t/g, '\\t')
           + "');return __p.join('');";
      var func = new Function('obj', '_', tmpl);
      if (data) return func(data, _);
      return function(data) {
        return func.call(this, data, _);
      };
    };
  
  var models      = [];
  var modelsHtml  = [];
  
  for (var i = 0; i < 250; i++) {
      var model = {
          prop1: 'prop1-' + i,
          prop2: 'prop2-' + i,
          prop3: 'prop3-' + i,
          prop4: 'prop4-' + i,
          prop5: 'prop5-' + i
      };
      
      models.push(model);
      
      modelsHtml.push(
          '<tr>' +
              '<td>' + model.prop1 + '</td>' +
              '<td>' + model.prop2 + '</td>' +
              '<td>' + model.prop3 + '</td>' +
              '<td>' + model.prop4 + '</td>' +
              '<td>' + model.prop5 + '</td>' +
          '</tr>'
      );
  }
  
  var models25        = models.slice(0, 25);
  var models50        = models.slice(0, 50);
  var models75        = models.slice(0, 75);
  var models100       = models.slice(0, 100);
  var models150       = models.slice(0, 150);
  var models200       = models.slice(0, 200);
  var models250       = models.slice(0, 250);
  
  var tableHtml25     = '<table>' + modelsHtml.slice(0, 25).join('') + '</table>';
  var tableHtml50     = '<table>' + modelsHtml.slice(0, 50).join('') + '</table>';
  var tableHtml75     = '<table>' + modelsHtml.slice(0, 75).join('') + '</table>';
  var tableHtml100    = '<table>' + modelsHtml.slice(0, 100).join('') + '</table>';
  var tableHtml150    = '<table>' + modelsHtml.slice(0, 150).join('') + '</table>';
  var tableHtml200    = '<table>' + modelsHtml.slice(0, 200).join('') + '</table>';
  var tableHtml250    = '<table>' + modelsHtml.slice(0, 250).join('') + '</table>';
  
  var domCreation     = document.getElementById('dom-creation');
  
  var template        = _.template(document.getElementById('template').innerHTML);
  var templateNoWith  = _.templateNoWith(document.getElementById('template-no-with').innerHTML);

};
</script>

Preparation code output

<div id="dom-creation" style="display: none;">container for creating nodes with innerHTML</div>

Test runner

Warning! For accurate results, please disable Firebug before running the tests. (Why?)

Java applet disabled.

Testing in CCBot 2.0.0 / Other 0.0.0
Test Ops/sec
innerHtml 25 rows
    var div     = domCreation.innerHTML = tableHtml25;
    var table   = domCreation.firstChild;
pending…
innerHtml 50 rows
    var div     = domCreation.innerHTML = tableHtml50;
    var table   = domCreation.firstChild;
pending…
innerHtml 75 rows
    var div     = domCreation.innerHTML = tableHtml75;
    var table   = domCreation.firstChild;
pending…
innerHtml 100 rows
    var div     = domCreation.innerHTML = tableHtml100;
    var table   = domCreation.firstChild;
pending…
innerHtml 150 rows
    var div     = domCreation.innerHTML = tableHtml150;
    var table   = domCreation.firstChild;
pending…
innerHtml 200 rows
    var div     = domCreation.innerHTML = tableHtml200;
    var table   = domCreation.firstChild;
pending…
innerHtml 250 rows
    var div     = domCreation.innerHTML = tableHtml250;
    var table   = domCreation.firstChild;
pending…
createElement 25 rows
    var table   = document.createElement('table');
    var models  = models25;
    var length  = models.length;
    
    for (var i = 0; i < models.length; i++) {
        var model   = models[i];
        var row     = document.createElement('tr');
        
        var cell1 = document.createElement('td');
        var text1 = document.createTextNode(model.prop1);
        cell1.appendChild(text1);
        row.appendChild(cell1);
        
        var cell2 = document.createElement('td');
        var text2 = document.createTextNode(model.prop2);
        cell2.appendChild(text2);
        row.appendChild(cell2);
        
        var cell3 = document.createElement('td');
        var text3 = document.createTextNode(model.prop3);
        cell3.appendChild(text3);
        row.appendChild(cell3);
        
        var cell4 = document.createElement('td');
        var text4 = document.createTextNode(model.prop4);
        cell4.appendChild(text4);
        row.appendChild(cell4);
        
        var cell5 = document.createElement('td');
        var text5 = document.createTextNode(model.prop5);
        cell5.appendChild(text5);
        row.appendChild(cell5);
        
        table.appendChild(row);
    }
pending…
createElement 50 rows
    var table   = document.createElement('table');
    var models  = models50;
    var length  = models.length;
    
    for (var i = 0; i < models.length; i++) {
        var model   = models[i];
        var row     = document.createElement('tr');
        
        var cell1 = document.createElement('td');
        var text1 = document.createTextNode(model.prop1);
        cell1.appendChild(text1);
        row.appendChild(cell1);
        
        var cell2 = document.createElement('td');
        var text2 = document.createTextNode(model.prop2);
        cell2.appendChild(text2);
        row.appendChild(cell2);
        
        var cell3 = document.createElement('td');
        var text3 = document.createTextNode(model.prop3);
        cell3.appendChild(text3);
        row.appendChild(cell3);
        
        var cell4 = document.createElement('td');
        var text4 = document.createTextNode(model.prop4);
        cell4.appendChild(text4);
        row.appendChild(cell4);
        
        var cell5 = document.createElement('td');
        var text5 = document.createTextNode(model.prop5);
        cell5.appendChild(text5);
        row.appendChild(cell5);
        
        table.appendChild(row);
    }
pending…
createElement 75 rows
    var table   = document.createElement('table');
    var models  = models75;
    var length  = models.length;
    
    for (var i = 0; i < models.length; i++) {
        var model   = models[i];
        var row     = document.createElement('tr');
        
        var cell1 = document.createElement('td');
        var text1 = document.createTextNode(model.prop1);
        cell1.appendChild(text1);
        row.appendChild(cell1);
        
        var cell2 = document.createElement('td');
        var text2 = document.createTextNode(model.prop2);
        cell2.appendChild(text2);
        row.appendChild(cell2);
        
        var cell3 = document.createElement('td');
        var text3 = document.createTextNode(model.prop3);
        cell3.appendChild(text3);
        row.appendChild(cell3);
        
        var cell4 = document.createElement('td');
        var text4 = document.createTextNode(model.prop4);
        cell4.appendChild(text4);
        row.appendChild(cell4);
        
        var cell5 = document.createElement('td');
        var text5 = document.createTextNode(model.prop5);
        cell5.appendChild(text5);
        row.appendChild(cell5);
        
        table.appendChild(row);
    }
pending…
createElement 100 rows
    var table   = document.createElement('table');
    var models  = models100;
    var length  = models.length;
    
    for (var i = 0; i < models.length; i++) {
        var model   = models[i];
        var row     = document.createElement('tr');
        
        var cell1 = document.createElement('td');
        var text1 = document.createTextNode(model.prop1);
        cell1.appendChild(text1);
        row.appendChild(cell1);
        
        var cell2 = document.createElement('td');
        var text2 = document.createTextNode(model.prop2);
        cell2.appendChild(text2);
        row.appendChild(cell2);
        
        var cell3 = document.createElement('td');
        var text3 = document.createTextNode(model.prop3);
        cell3.appendChild(text3);
        row.appendChild(cell3);
        
        var cell4 = document.createElement('td');
        var text4 = document.createTextNode(model.prop4);
        cell4.appendChild(text4);
        row.appendChild(cell4);
        
        var cell5 = document.createElement('td');
        var text5 = document.createTextNode(model.prop5);
        cell5.appendChild(text5);
        row.appendChild(cell5);
        
        table.appendChild(row);
    }
pending…
createElement 150 rows
    var table   = document.createElement('table');
    var models  = models150;
    var length  = models.length;
    
    for (var i = 0; i < models.length; i++) {
        var model   = models[i];
        var row     = document.createElement('tr');
        
        var cell1 = document.createElement('td');
        var text1 = document.createTextNode(model.prop1);
        cell1.appendChild(text1);
        row.appendChild(cell1);
        
        var cell2 = document.createElement('td');
        var text2 = document.createTextNode(model.prop2);
        cell2.appendChild(text2);
        row.appendChild(cell2);
        
        var cell3 = document.createElement('td');
        var text3 = document.createTextNode(model.prop3);
        cell3.appendChild(text3);
        row.appendChild(cell3);
        
        var cell4 = document.createElement('td');
        var text4 = document.createTextNode(model.prop4);
        cell4.appendChild(text4);
        row.appendChild(cell4);
        
        var cell5 = document.createElement('td');
        var text5 = document.createTextNode(model.prop5);
        cell5.appendChild(text5);
        row.appendChild(cell5);
        
        table.appendChild(row);
    }
pending…
createElement 200 rows
    var table   = document.createElement('table');
    var models  = models200;
    var length  = models.length;
    
    for (var i = 0; i < models.length; i++) {
        var model   = models[i];
        var row     = document.createElement('tr');
        
        var cell1 = document.createElement('td');
        var text1 = document.createTextNode(model.prop1);
        cell1.appendChild(text1);
        row.appendChild(cell1);
        
        var cell2 = document.createElement('td');
        var text2 = document.createTextNode(model.prop2);
        cell2.appendChild(text2);
        row.appendChild(cell2);
        
        var cell3 = document.createElement('td');
        var text3 = document.createTextNode(model.prop3);
        cell3.appendChild(text3);
        row.appendChild(cell3);
        
        var cell4 = document.createElement('td');
        var text4 = document.createTextNode(model.prop4);
        cell4.appendChild(text4);
        row.appendChild(cell4);
        
        var cell5 = document.createElement('td');
        var text5 = document.createTextNode(model.prop5);
        cell5.appendChild(text5);
        row.appendChild(cell5);
        
        table.appendChild(row);
    }
pending…
createElement 250 rows
    var table   = document.createElement('table');
    var models  = models250;
    var length  = models.length;
    
    for (var i = 0; i < models.length; i++) {
        var model   = models[i];
        var row     = document.createElement('tr');
        
        var cell1 = document.createElement('td');
        var text1 = document.createTextNode(model.prop1);
        cell1.appendChild(text1);
        row.appendChild(cell1);
        
        var cell2 = document.createElement('td');
        var text2 = document.createTextNode(model.prop2);
        cell2.appendChild(text2);
        row.appendChild(cell2);
        
        var cell3 = document.createElement('td');
        var text3 = document.createTextNode(model.prop3);
        cell3.appendChild(text3);
        row.appendChild(cell3);
        
        var cell4 = document.createElement('td');
        var text4 = document.createTextNode(model.prop4);
        cell4.appendChild(text4);
        row.appendChild(cell4);
        
        var cell5 = document.createElement('td');
        var text5 = document.createTextNode(model.prop5);
        cell5.appendChild(text5);
        row.appendChild(cell5);
        
        table.appendChild(row);
    }
pending…
jQuery 25 rows
var table = $(tableHtml25);
pending…
jQuery 50 rows
var table = $(tableHtml50);
pending…
jQuery 75 rows
var table = $(tableHtml75);
pending…
jQuery 100 rows
var table = $(tableHtml100);
pending…
jQuery 150 rows
var table = $(tableHtml150);
pending…
jQuery 200 rows
var table = $(tableHtml200);
pending…
jQuery 250 rows
var table = $(tableHtml250);
pending…
underscore.js 25 rows
var table = $(template({ models: models25 }));
pending…
underscore.js 50 rows
var table = $(template({ models: models50 }));
pending…
underscore.js 75 rows
var table = $(template({ models: models75 }));
pending…
underscore.js 100 rows
var table = $(template({ models: models100 }));
pending…
underscore.js 150 rows
var table = $(template({ models: models150 }));
pending…
underscore.js 200 rows
var table = $(template({ models: models200 }));
pending…
underscore.js 250 rows
var table = $(template({ models: models250 }));
pending…
underscore.js no with 25 rows
var table = $(templateNoWith({ models: models25 }));
pending…
underscore.js no with 50 rows
var table = $(templateNoWith({ models: models50 }));
pending…
underscore.js no with 75 rows
var table = $(templateNoWith({ models: models75 }));
pending…
underscore.js no with 100 rows
var table = $(templateNoWith({ models: models100 }));
pending…
underscore.js no with 150 rows
var table = $(templateNoWith({ models: models150 }));
pending…
underscore.js no with 200 rows
var table = $(templateNoWith({ models: models200 }));
pending…
underscore.js no with 250 rows
var table = $(templateNoWith({ models: models250 }));
pending…

Compare results of other browsers

Revisions

You can edit these tests or add even more tests to this page by appending /edit to the URL.

0 Comments