JS templating benchmarks

JavaScript performance comparison

Test case created

Info

Compare templating engines that generate html strings.

Preparation code

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="http://documentcloud.github.com/underscore/underscore-min.js"></script>
<script src="https://raw.github.com/janl/mustache.js/master/mustache.js"></script>
<script src="https://raw.github.com/BorisMoore/jsrender/master/jsrender.js"></script>
<script src="https://github.com/downloads/wycats/handlebars.js/handlebars.runtime-1.0.0.beta.6" type="text/javascript"></script>
<script type="text/javascript">
    var rows = [];

    for (var i = 0; i < 100; i++) {
        var row = {
          id: i,
          firstName: 'john',
          lastName: 'doe'
        };

        rows.push(row);
      }

    var underscoreTmpl = "\
    <table>\
    <%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 ><%}%>\
    </table>"
;

 var mustacheTmpl = "\
    <table>\
    {{#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}}\
    <table>"
;

    var jsRenderTmpl = "\
    <table>\
    {{#each 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 >\
    {{/each}}\
    </table>"
;

$.template("compiledTemplate", jsRenderTmpl);

// Handlebars

(function() {
  var template = Handlebars.template, templates = Handlebars.templates = Handlebars.templates || {};
templates['table'] = template(function (Handlebars,depth0,helpers,partials,data) {
  helpers = helpers || Handlebars.helpers;
  var buffer = "", stack1, tmp1, self=this, functionType="function", helperMissing=helpers.helperMissing, undef=void 0, escapeExpression=this.escapeExpression, blockHelperMissing=helpers.blockHelperMissing;

function program1(depth0,data) {
 
  var buffer = "", stack1;
  buffer += "\n<tr> \n  <td> <input type = 'checkbox' value = '";
  stack1 = helpers.id || depth0.id;
  if(typeof stack1 === functionType) { stack1 = stack1.call(depth0, { hash: {} }); }
  else if(stack1=== undef) { stack1 = helperMissing.call(depth0, "id", { hash: {} }); }
  buffer += escapeExpression(stack1) + "' /> </td>\n  <td>";
  stack1 = helpers.firstname || depth0.firstname;
  if(typeof stack1 === functionType) { stack1 = stack1.call(depth0, { hash: {} }); }
  else if(stack1=== undef) { stack1 = helperMissing.call(depth0, "firstname", { hash: {} }); }
  buffer += escapeExpression(stack1) + " ";
  stack1 = helpers.lastname || depth0.lastname;
  if(typeof stack1 === functionType) { stack1 = stack1.call(depth0, { hash: {} }); }
  else if(stack1=== undef) { stack1 = helperMissing.call(depth0, "lastname", { hash: {} }); }
  buffer += escapeExpression(stack1) + "</td> \n  <td class = 'edit'> \n    <a> Edit </a>\n    <input style='display:none;' type='hidden' value='Blah' /> \n    <input class = 'cancel' type = 'button' value = 'cancel' /> \n  </td>\n  <td class='select'>\n      <a>Select</a> \n      <select style = 'display:none;'> \n        <option>0</option>\n        <option>1</option> \n        <option>2</option>\n        <option>3</option> \n        <option>4</option>\n        <option>5</option> \n        <option>6</option>\n        <option>7</option> \n        <option>8</option>\n        <option>9</option> \n        <option>10</option>\n       </select> \n        <input class = 'cancel' type = 'button' value = 'cancel' /> \n   </td>\n   <td>More string</td> \n   <td>More string</td>\n   <td>More string</td> \n   <td>More string</td>\n   <td>More string</td> \n   <td>More string</td>\n</tr >";
  return buffer;}

  buffer += "<table>\n";
  stack1 = helpers.rows || depth0.rows;
  tmp1 = self.program(1, program1, data);
  tmp1.hash = {};
  tmp1.fn = tmp1;
  tmp1.inverse = self.noop;
  if(typeof stack1 === functionType) { stack1 = stack1.call(depth0, tmp1); }
  else { stack1 = blockHelperMissing.call(depth0, stack1, tmp1); }
  if(stack1 || stack1 === 0) { buffer += stack1; }
  buffer += "\n<table>\n\n";
  return buffer;});
})()


</script>

<script type="text/html" id="icanhazTmpl">
    <table>
    {{#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}}
    </table>
</script>
 

Preparation code output

Test runner

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

Java applet disabled.

Testing in unknown unknown
Test Ops/sec
jsrender
$.render({rows: rows}, jsRenderTmpl);
pending…
jsrender compiled
$.render({rows: rows}, "compiledTemplate");
pending…
underscore
_.template(underscoreTmpl)({rows: rows});
pending…
mustache
Mustache.to_html(mustacheTmpl, {rows: rows});
pending…
Handlebars.js
Handlebars.templates.table({rows: rows});
pending…

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

Compare results of other browsers

0 comments

Add a comment