Performance comparison of jQuery Template vs underscore vs string append for table

JavaScript performance comparison

Revision 50 of this test case created by Mauricio Wolff

Preparation code

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js">
</script>
<script src="http://github.com/jquery/jquery-tmpl/raw/master/jquery.tmpl.js">
</script>
<script src="http://documentcloud.github.com/underscore/underscore.js">
</script>
<script src="http://github.com/mhevery/mustache.js/raw/dot-notation/mustache.js">
</script>
<script src="http://github.com/pvande/Milk/raw/master/dist/v1.2.0/milk.js">
</script>
<script>
  $(function() {
    $('body').delegate('#table .edit a, #table .select a', 'click', function() {
      var $td = $(this).closest('td');
      $td.find('input, select').show();
      $td.find('a').hide();
    });

    $('body').delegate('#table .edit .cancel, $table .select .cancel', 'click', function() {
      var $td = $(this).closest('td');
      $td.find('input, select').hide();
      $td.find('a').show();
    });
  });
</script>
<script type="text/x-jquery-tmpl" id="tmplRow">
  < tr > < td > < input type = "checkbox"
  value = "${id}" / > < /td>
  <td>${firstName} ${lastName}</td > < td class = "edit" > < a > Edit < /a>
    <input style="display:none;" type="hidden" value="Blah" / > < input class = "cancel"
  type = "button"
  value = "cancel" / > < /td>
  <td class="select">
      <a>Select</a > < select style = "display:none;" > < option > 0 < /option>
        <option>1</option > < option > 2 < /option>
        <option>3</option > < option > 4 < /option>
        <option>5</option > < option > 6 < /option>
        <option>7</option > < option > 8 < /option>
        <option>9</option > < option > 10 < /option>
       </select > < input class = "cancel"
  type = "button"
  value = "cancel" / > < /td>
   <td>More string</td > < td > More string < /td>
   <td>More string</td > < td > More string < /td>
   <td>More string</td > < td > More string < /td>
</tr >
</script>
var data = []; for (var i = 0; i
< 100; i++) { var row={ id: i, firstName: 'john', lastName: 'doe' }; data.push(row);
} $.template( "savedTmpl", document.getElementById( "tmplRow").innerHTML); var underscoreTmpl="\
<%for(var i=0;i<rows.length;i++){%>\
<%var row=rows[i];%> \
<tr> \
<td> <input type = 'checkbox' value = '<%= row.id%>' /> </td>\
<td><%= row.firstname%> <%= row.lastname%></td> \
<td class = 'edit'> \
<a> Edit </a>\
<input style='display:none;' type='hidden' value='Blah' /> \
<input class = 'cancel' type = 'button' value = 'cancel' /> \
</td>\
<td class='select'>\
<a>Select</a> \
<select style = 'display:none;'> \
<option>0</option>\
<option>1</option> \
<option>2</option>\
<option>3</option> \
<option>4</option>\
<option>5</option> \
<option>6</option>\
<option>7</option> \
<option>8</option>\
<option>9</option> \
<option>10</option>\
</select> \
<input class = 'cancel' type = 'button' value = 'cancel' /> \
</td>\
<td>More string</td> \
<td>More string</td>\
<td>More string</td> \
<td>More string</td>\
<td>More string</td> \
<td>More string</td>\
</tr ><%}%>" ; var mustacheTmpl="\
{{#rows}}\
<tr> \
<td> <input type = 'checkbox' value = '{{id}}' /> </td>\
<td>{{firstname}} {{lastname}}</td> \
<td class = 'edit'> \
<a> Edit </a>\
<input style='display:none;' type='hidden' value='Blah' /> \
<input class = 'cancel' type = 'button' value = 'cancel' /> \
</td>\
<td class='select'>\
<a>Select</a> \
<select style = 'display:none;'> \
<option>0</option>\
<option>1</option> \
<option>2</option>\
<option>3</option> \
<option>4</option>\
<option>5</option> \
<option>6</option>\
<option>7</option> \
<option>8</option>\
<option>9</option> \
<option>10</option>\
</select> \
<input class = 'cancel' type = 'button' value = 'cancel' /> \
</td>\
<td>More string</td> \
<td>More string</td>\
<td>More string</td> \
<td>More string</td>\
<td>More string</td> \
<td>More string</td>\
</tr >{{/rows}}" ; var milkTmpl="\
{{#rows}}\
<tr> \
<td> <input type = 'checkbox' value = '{{id}}' /> </td>\
<td>{{firstname}} {{lastname}}</td> \
<td class = 'edit'> \
<a> Edit </a>\
<input style='display:none;' type='hidden' value='Blah' /> \
<input class = 'cancel' type = 'button' value = 'cancel' /> \
</td>\
<td class='select'>\
<a>Select</a> \
<select style = 'display:none;'> \
<option>0</option>\
<option>1</option> \
<option>2</option>\
<option>3</option> \
<option>4</option>\
<option>5</option> \
<option>6</option>\
<option>7</option> \
<option>8</option>\
<option>9</option> \
<option>10</option>\
</select> \
<input class = 'cancel' type = 'button' value = 'cancel' /> \
</td>\
<td>More string</td> \
<td>More string</td>\
<td>More string</td> \
<td>More string</td>\
<td>More string</td> \
<td>More string</td>\
</tr >{{/rows}}" </script>
    

Preparation code output

<script src="http://github.com/jquery/jquery-tmpl/raw/master/jquery.tmpl.js"> </script> <script src="http://documentcloud.github.com/underscore/underscore.js"> </script> <script src="http://github.com/mhevery/mustache.js/raw/dot-notation/mustache.js"> </script> <script src="http://github.com/pvande/Milk/raw/master/dist/v1.2.0/milk.js"> </script> <script> $(function() { $('body').delegate('#table .edit a, #table .select a', 'click', function() { var $td = $(this).closest('td'); $td.find('input, select').show(); $td.find('a').hide(); }); $('body').delegate('#table .edit .cancel, $table .select .cancel', 'click', function() { var $td = $(this).closest('td'); $td.find('input, select').hide(); $td.find('a').show(); }); }); </script> <script type="text/x-jquery-tmpl" id="tmplRow"> < tr > < td > < input type = "checkbox" value = "${id}" / > < /td> <td>${firstName} ${lastName}</td > < td class = "edit" > < a > Edit < /a> <input style="display:none;" type="hidden" value="Blah" / > < input class = "cancel" type = "button" value = "cancel" / > < /td> <td class="select"> <a>Select</a > < select style = "display:none;" > < option > 0 < /option> <option>1</option > < option > 2 < /option> <option>3</option > < option > 4 < /option> <option>5</option > < option > 6 < /option> <option>7</option > < option > 8 < /option> <option>9</option > < option > 10 < /option> </select > < input class = "cancel" type = "button" value = "cancel" / > < /td> <td>More string</td > < td > More string < /td> <td>More string</td > < td > More string < /td> <td>More string</td > < td > More string < /td> </tr > </script> var data = []; for (var i = 0; i < 100; i++) { var row={ id: i, firstName: 'john', lastName: 'doe' }; data.push(row); } $.template( "savedTmpl", document.getElementById( "tmplRow").innerHTML); var underscoreTmpl="\ <%for(var i=0;i<rows.length;i++){%>\ <%var row=rows[i];%> \ <tr> \ <td> <input type = 'checkbox' value = '<%= row.id%>' /> </td>\ <td><%= row.firstname%> <%= row.lastname%></td> \ <td class = 'edit'> \ <a> Edit </a>\ <input style='display:none;' type='hidden' value='Blah' /> \ <input class = 'cancel' type = 'button' value = 'cancel' /> \ </td>\ <td class='select'>\ <a>Select</a> \ <select style = 'display:none;'> \ <option>0</option>\ <option>1</option> \ <option>2</option>\ <option>3</option> \ <option>4</option>\ <option>5</option> \ <option>6</option>\ <option>7</option> \ <option>8</option>\ <option>9</option> \ <option>10</option>\ </select> \ <input class = 'cancel' type = 'button' value = 'cancel' /> \ </td>\ <td>More string</td> \ <td>More string</td>\ <td>More string</td> \ <td>More string</td>\ <td>More string</td> \ <td>More string</td>\ </tr ><%}%>" ; var mustacheTmpl="\ {{#rows}}\ <tr> \ <td> <input type = 'checkbox' value = '{{id}}' /> </td>\ <td>{{firstname}} {{lastname}}</td> \ <td class = 'edit'> \ <a> Edit </a>\ <input style='display:none;' type='hidden' value='Blah' /> \ <input class = 'cancel' type = 'button' value = 'cancel' /> \ </td>\ <td class='select'>\ <a>Select</a> \ <select style = 'display:none;'> \ <option>0</option>\ <option>1</option> \ <option>2</option>\ <option>3</option> \ <option>4</option>\ <option>5</option> \ <option>6</option>\ <option>7</option> \ <option>8</option>\ <option>9</option> \ <option>10</option>\ </select> \ <input class = 'cancel' type = 'button' value = 'cancel' /> \ </td>\ <td>More string</td> \ <td>More string</td>\ <td>More string</td> \ <td>More string</td>\ <td>More string</td> \ <td>More string</td>\ </tr >{{/rows}}" ; var milkTmpl="\ {{#rows}}\ <tr> \ <td> <input type = 'checkbox' value = '{{id}}' /> </td>\ <td>{{firstname}} {{lastname}}</td> \ <td class = 'edit'> \ <a> Edit </a>\ <input style='display:none;' type='hidden' value='Blah' /> \ <input class = 'cancel' type = 'button' value = 'cancel' /> \ </td>\ <td class='select'>\ <a>Select</a> \ <select style = 'display:none;'> \ <option>0</option>\ <option>1</option> \ <option>2</option>\ <option>3</option> \ <option>4</option>\ <option>5</option> \ <option>6</option>\ <option>7</option> \ <option>8</option>\ <option>9</option> \ <option>10</option>\ </select> \ <input class = 'cancel' type = 'button' value = 'cancel' /> \ </td>\ <td>More string</td> \ <td>More string</td>\ <td>More string</td> \ <td>More string</td>\ <td>More string</td> \ <td>More string</td>\ </tr >{{/rows}}" </script>

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
jQuery templates
var html1 = $("#tmplRow").tmpl(data)
pending…
string padding method
var s = [];

for (var i = 0; i < 100; i++) {
  s.push('<tr>');
  s.push('<td><input type="checkbox" value="');
  s.push(data[i].id);
  s.push('" /></td><td>');
  s.push(data[i].firstName + ' ');
  s.push(data[i].lastName);
  s.push('</td>');
  s.push('<td class="edit">        <a>Edit</a>        <input style="display:none;" type="hidden" value="Blah" />        <input class="cancel" type="button" value="cancel" />    </td>    <td class="select">        <a>Select</a>        <select style="display:none;">            <option>0</option>            <option>1</option>            <option>2</option>            <option>3</option>            <option>4</option>            <option>5</option>            <option>6</option>            <option>7</option>            <option>8</option>            <option>9</option>            <option>10</option>        </select>        <input class="cancel" type="button" value="cancel" />    </td>    <td>More string</td>    <td>More string</td>    <td>More string</td>    <td>More string</td>    <td>More string</td>    <td>More string</td>');
  s.push('</tr>');
}

var html2 = s.join('');
pending…
Precompiled jQuery template
var html3 = $.tmpl("savedTmpl", data);
pending…
Underscore.js
var html4 = _.template(underscoreTmpl, {
  rows: data
});
pending…
mustache js
Mustache.to_html(mustacheTmpl, {
  rows: data
});
pending…
mustache Milk
Milk.render(milkTmpl, {
  rows: data
});
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

var data = []; for (var i = 0; i < 100; i++) { var row={ id: i, firstName: 'john', lastName: 'doe' }; data.push(row); } $.template( "savedTmpl", document.getElementById( "tmplRow").innerHTML); var underscoreTmpl="\ <%for(var i=0;i\ <%var row=rows[i];%> \ \ \ <%= row.firstname%> <%= row.lastname%> \ \ Edit \ \ \ \ \ Select \ \ \ \ More string \ More string\ More string \ More string\ More string \ More string\ <%}%>" ; var mustacheTmpl="\ {{#rows}}\ \ \ {{firstname}} {{lastname}} \ \ Edit \ \ \ \ \ Select \ \ \ \ More string \ More string\ More string \ More string\ More string \ More string\ {{/rows}}" ; var milkTmpl="\ {{#rows}}\ \ \ {{firstname}} {{lastname}} \ \ Edit \ \ \ \ \ Select \ \ \ \ More string \ More string\ More string \ More string\ More string \ More string\ {{/rows}}"