Mustache JS engine rumble: Mustache.js vs Handlebars.js vs Hogan.js vs templayed.js vs mote.js

JavaScript performance comparison

Revision 20 of this test case created and last updated

Info

Compared Mustache.js, Handlebars.js, Hogan.js, templayed.js and mote.js.

Preparation code

<script src="https://raw.github.com/janl/mustache.js/master/mustache.js"></script>
<script src="http://cloud.github.com/downloads/wycats/handlebars.js/handlebars-1.0.0.beta.6.js"></script>
<script src="https://raw.github.com/twitter/hogan.js/master/web/builds/2.0.0/hogan-2.0.0.min.js"></script>
<script src="https://raw.github.com/archan937/templayed.js/master/src/templayed.js"></script>
<script src="http://satchmorun.github.com/mote/mote.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/1.0.0-rc.2/lodash.min.js"></script>

<script>
  var lodash = _.noConflict();
</script>
 
<script>
Benchmark.prototype.setup = function() {
    var tests = [
      {
        template: "<p>My name is {{name}}!</p>",
        variables: {name: "Paul Engel"}
      }, {
        template: "<p>My name is {{name}}!{{!name}}</p>",
        variables: {name: "Paul Engel"}
      }, {
        template: "<p>{{html}} {{&html}}</p>",
        variables: {html: "<strong>Paul Engel</strong>"}
      }, {
        template: "<p>{{html}} {{{html}}}</p>",
        variables: {html: "<strong>Paul Engel</strong>"}
      }, {
        template: "<p>This is shown!{{#show}} Psst, this is never shown{{/show}}</p>",
        variables: {}
      }, {
        template: "<p>This is shown!{{#show}} Psst, this is never shown{{/show}}</p>",
        variables: {show: false}
      }, {
        template: "<p>This is shown!{{#shown}} And, this is also shown{{/shown}}</p>",
        variables: {shown: true}
      }, {
        template: "<p>My name is {{person.first_name}} {{person.last_name}}!</p>",
        variables: {person: {first_name: "Paul", last_name: "Engel"}}
      }, {
        template: "{{name}}<ul>{{#names}}<li>{{name}}</li>{{/names}}</ul>{{^names}}Sorry, no people to list!{{/names}}",
        variables: {names: []}
      }, {
        template: "<p>{{name}}</p><ul>{{#names}}<li>{{name}}</li>{{/names}}</ul>{{^names}}Sorry, no people to list!{{/names}}<p>{{name}}</p>",
        variables: {name: "Chunk Norris", names: [{name: "Paul"}, {name: "Engel"}]}
      }, {
        template: "<ul>{{#names}}<li>{{.}}{{foo}}</li>{{/names}}</ul>",
        variables: {names: ["Paul", "Engel"]}
      }, {
        template: "<ul>{{#names}}<li>{{fullName}}</li>{{/names}}</ul>",
        variables: {
          names: [{firstName: "Paul", lastName: "Engel"}, {firstName: "Chunk", lastName: "Norris"}],
          fullName: function() {
            return this.lastName + ", " + this.firstName;
          }
        }
      }
    ];
    var compiled = {
      "Mustache.js": [],
      "Handlebars.js": [],
      "Hogan.js": [],
      "templayed.js": [],
      "mote.js": []
    };
    for (var i = 0; i < tests.length; i++) {
      var template = tests[i].template;
      compiled["Mustache.js"  ].push(template.replace(/\.\.\//g, ""));
      compiled["Handlebars.js"].push(Handlebars.compile(template));
      compiled["Hogan.js"     ].push(Hogan.compile(template.replace(/\.\.\//g, "")));
      compiled["templayed.js" ].push(templayed(template));
      compiled["mote.js"].push(mote.compile(template));
    }
   
    var _ = window.lodash;
   
    var template = '<div class="item <%= id %>">' +
                   '  <h1><%= title %></h1>' +
                   '  <p><%= desc %></p>' +
                   '  <ul class="attributes">' +
                   '    <li><%= attrs.dimensions %></li>' +
                   '    <li><%= attrs.weight %></li>' +
                   '    <li><%= attrs.price %></li>' +
                   '  </ul>' +
                   '</div>';
   
    var templateFuncPrecompiled = eval("(" + _.template(template).source + ")");
};
</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
Mustache.js
for (var i = 0; i < tests.length; i++) {
  Mustache.to_html(compiled["Mustache.js"][i], tests[i].variables);
}
pending…
Handlebars.js
for (var i = 0; i < tests.length; i++) {
  compiled["Handlebars.js"][i](tests[i].variables);
}
pending…
Hogan.js
for (var i = 0; i < tests.length; i++) {
  compiled["Hogan.js"][i].render(tests[i].variables);
}
pending…
templayed.js
for (var i = 0; i < tests.length; i++) {
  compiled["templayed.js"][i](tests[i].variables);
}
pending…
mote.js
for (var i = 0; i < tests.length; i++) {
  compiled["mote.js"][i](tests[i].variables);
}
pending…
classic underscore
var templateFunc = _.template(template);  // compile template
var output = templateFunc({               // render template
  id: 5,
  title : 'Hello World!',
  desc  : 'Ordianry item',
  attrs : {
    dimensions : '100cm x 100cm x 20cm',
    weight     : '15kg',
    price      : '10EUR'
  }
});
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. Here’s a list of current revisions for this page:

0 comments

Add a comment