Mustache JS engine rumble: Mustache.js vs Handlebars.js vs Hogan.js vs templayed.js vs mote.js vs ect (v22)

Revision 22 of this benchmark created on


Description

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

Preparation HTML

<script src="https://raw.github.com/janl/mustache.js/master/mustache.js">
</script>
<script src="https://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="https://satchmorun.github.com/mote/mote.js">
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/1.0.0-rc.2/lodash.min.js">
</script>
<!-- For compile the template with ECT -->
<script src="https://raw.github.com/jashkenas/coffee-script/master/extras/coffee-script.js">
</script>
<script src="https://raw.github.com/baryshev/ect/master/ect.min.js">
</script>
<script>
  var lodash = _.noConflict();
</script>

Setup

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 + ")");
    
    var data = {
      id: 5,
      title: 'Hello World!',
      desc: 'Ordianry item',
      attrs: {
        dimensions: '100cm x 100cm x 20cm',
        weight: '15kg',
        price: '10EUR'
      }
    };
    
      var ect_render = new ECT({
        root: {'page': template},
        cache: true,
        debug: true
      });

Test runner

Ready to run.

Testing in
TestOps/sec
Mustache.js
for (var i = 0; i < tests.length; i++) {
  Mustache.to_html(compiled["Mustache.js"][i], tests[i].variables);
}
ready
Handlebars.js
for (var i = 0; i < tests.length; i++) {
  compiled["Handlebars.js"][i](tests[i].variables);
}
ready
Hogan.js
for (var i = 0; i < tests.length; i++) {
  compiled["Hogan.js"][i].render(tests[i].variables);
}
ready
templayed.js
for (var i = 0; i < tests.length; i++) {
  compiled["templayed.js"][i](tests[i].variables);
}
ready
mote.js
for (var i = 0; i < tests.length; i++) {
  compiled["mote.js"][i](tests[i].variables);
}
ready
classic underscore
var templateFunc = _.template(template); // compile template
var output = templateFunc(data);
ready
ECT
var html = ect_render.render('page', data);
ready

Revisions

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