JavaScript template language shootoff (v568)

Revision 568 of this benchmark created by Indamix on


Description

A brief comparison of some JavaScript templating engines on a short template: 6 header tags, and 10 list items.

Added doT, doU and jQote2 to benchmarks.

Added jqml to benchmarks.

Results that output strings are attached using innerHTML to discover actual DOM performance.

noHtml should be using reduce(). Not forEach, which doesn't return anything.

Added BabaJS to benchmarks. Precompile BabaJS template once.

Preparation HTML

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>

<script src="https://raw.github.com/seznam/JAK/master/lib/jak.js"></script>
<script src="https://raw.github.com/seznam/JAK/master/util/template/template.js"></script>

<script src="http://documentcloud.github.com/underscore/underscore.js"></script>

<script src="http://github.com/hij1nx/JUP/raw/master/lib/jup.js"></script>

<script src="http://github.com/janl/mustache.js/raw/master/mustache.js"></script>

<script src="https://github.com/downloads/paul/handlebars.js/handlebars.js"></script>

<script src="http://gist.github.com/raw/550881/29bb186167079c0b33ab6e9d50d779f37860cfa4/micro.js"></script>

<script src="http://github.com/creationix/haml-js/raw/master/lib/haml.js"></script>

<script src="http://gist.github.com/raw/550723/12d176698628e30a1df398c7ac7aea93924e1294/jade.js"></script>

<script src="http://jashkenas.github.com/coffee-script/extras/coffee-script.js"></script>
<script src="http://sstephenson.github.com/eco/dist/eco.js"></script>

<script src="http://ajax.microsoft.com/ajax/jquery.templates/beta1/jquery.tmpl.min.js"></script>

<script src="https://github.com/olado/doT/raw/master/doT.js"></script>

<script src="https://github.com/olado/doT/raw/master/doU.js"></script>

<script src="https://raw.github.com/mobz/nohtml/master/src/jquery-nohtml.js"></script>

<script src="http://github.com/aefxx/jQote2/raw/69b2053a13f5f180e696de9b3dba856a3c00678c/jquery.jqote2.js"></script>

<script src="https://raw.github.com/relativityboy/Orange-J/master/jquery.orange.js"></script>

<script src="https://raw.github.com/trevnorris/jqml/master/src/jqml.min.js"></script>

<script src="https://raw.github.com/mrharel/babajs/master/babajs.js"></script>

<script>
  window.mustacheTemplate = "<div><h1 class='header'>{{header}}</h1><h2 class='header2'>{{header2}}</h2><h3 class='header3'>{{header3}}</h3><h4 class='header4'>{{header4}}</h4><h5 class='header5'>{{header5}}</h5><h6 class='header6'>{{header6}}</h6><ul class='list'>{{#list}}<li class='item'>{{.}}</li>{{/list}}</ul></div>";

  window.handlebarsTemplate = Handlebars.compile("<div><h1 class='header'>{{header}}</h1><h2 class='header2'>{{header2}}</h2><h3 class='header3'>{{header3}}</h3><h4 class='header4'>{{header4}}</h4><h5 class='header5'>{{header5}}</h5><h6 class='header6'>{{header6}}</h6><ul class='list'>{{#list}}<li class='item'>{{this}}</li>{{/list}}</ul></div>");

  window.micro = "<div><h1 class='header'><%= header %></h1><h2 class='header2'><%= header2 %></h2><h3 class='header3'><%= header3 %></h3><h4 class='header4'><%= header4 %></h4><h5 class='header5'><%= header5 %></h5><h6 class='header6'><%= header6 %></h6><ul class='list'><% for (var i = 0, l = list.length; i < l; i++) { %><li class='item'><%= list[i] %></li><% } %></ul></div>";

  window.underscoreTemplate = _.template(micro);

  window.resigTemplate = tmpl(micro);

  window.jakTemplate = new JAK.Template(window.mustacheTemplate);

  window.sharedVariables = {
   header: "Header",
   header2: "Header2",
   header3: "Header3",
   header4: "Header4",
   header5: "Header5",
   header6: "Header6",
   list: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10']
  };

  window.jupTemplate = ['div', ['h1',
  {
   'class': 'header'
  }, "{{header}}"],
   ['h2',
   {
    'class': 'header2'
   }, "{{header2}}"],
   ['h3',
   {
    'class': 'header3'
   }, "{{header3}}"],
   ['h4',
   {
    'class': 'header4'
   }, "{{header4}}"],
   ['h5',
   {
    'class': 'header5'
   }, "{{header5}}"],
   ['h6',
   {
    'class': 'header6'
   }, "{{header6}}"],
   ['ul',
   {
    'class': 'list'
   }, ['li',
   {
    'class': 'item'
   }, '{{list}}'],
    ['li',
    {
     'class': 'item'
    }, '{{list}}'],
    ['li',
    {
     'class': 'item'
    }, '{{list}}'],
    ['li',
    {
     'class': 'item'
    }, '{{list}}'],
    ['li',
    {
     'class': 'item'
    }, '{{list}}'],
    ['li',
    {
     'class': 'item'
    }, '{{list}}'],
    ['li',
    {
     'class': 'item'
    }, '{{list}}'],
    ['li',
    {
     'class': 'item'
    }, '{{list}}'],
    ['li',
    {
     'class': 'item'
    }, '{{list}}'],
    ['li',
    {
     'class': 'item}'
    }, '{{list}}']
   ]
  ];

  window.jqmlTemplate = ['div',
      ['h1', sharedVariables.header, {'class': 'header'}],
      ['h2', sharedVariables.header2, {'class': 'header2'}],
      ['h3', sharedVariables.header3, {'class': 'header3'}],
      ['h4', sharedVariables.header4, {'class': 'header4'}],
      ['h5', sharedVariables.header5, {'class': 'header5'}],
      ['h6', sharedVariables.header6, {'class': 'header6'}],
      (function() {
        var list = ['ul'];
        for (var i = 0; i < sharedVariables.list.length; i++) {
          list.push(['li', sharedVariables.list[i], {'class': 'item'}]);
        }
        return list;
      }())
    ];

  window.jadeTemplate = "div\n  h1.header!= header\n  h2.header2!= header2\n  h3.header3!= header3\n  h4.header4!= header4\n  h5.header5!= header5\n  h6.header6!= header6\n  ul.list\n    - each item in list\n      li.item!= item";

  window.hamlTemplate = Haml("%div\n  %h1.header= header\n  %h2.header2= header2\n  %h3.header3= header3\n  %h4.header4= header4\n  %h5.header5= header5\n  %h6.header6= header6\n  %ul.list\n    :each item in list\n      %li.item= item");

  window.ecoTemplate = eco("<div><h1 class='header'><%- @header %></h1><h2 class='header2'><%- @header2 %></h2><h3 class='header3'><%- @header3 %></h3><h4 class='header4'><%- @header4 %></h4><h5 class='header5'><%- @header5 %></h5><h6 class='header6'><%- @header6 %></h6><ul class='list'><% for item in @list: %><li class='item'><%- item %></li><% end %></ul></div>");

  window.jQueryTemplate = $.template(null, "<div><h1 class='header'>${header}</h1><h2 class='header2'>${header2}</h2><h3 class='header3'>${header3}</h3><h4 class='header4'>${header4}</h4><h5 class='header5'>${header5}</h5><h6 class='header6'>${header6}</h6><ul class='list'>{{each list}}<li class='item'>${$value}</li>{{/each}}</ul></div>");

  window.doTtemplate = doT.template("<div><h1 class='header'>{{= it.header }}</h1><h2 class='header2'>{{= it.header2 }}</h2><h3 class='header3'>{{= it.header3 }}</h3><h4 class='header4'>{{= it.header4 }}</h4><h5 class='header5'>{{= it.header5 }}</h5><h6 class='header6'>{{= it.header6 }}</h6><ul class='list'>{{ for (var i = 0, l = it.list.length; i < l; i++) { }}<li class='item'>{{= it.list[i] }}</li>{{ } }}</ul></div>");

  window.doUtemplate = doU.template("<div><h1 class='header'>{{= it.header }}</h1><h2 class='header2'>{{= it.header2 }}</h2><h3 class='header3'>{{= it.header3 }}</h3><h4 class='header4'>{{= it.header4 }}</h4><h5 class='header5'>{{= it.header5 }}</h5><h6 class='header6'>{{= it.header6 }}</h6><ul class='list'>{{ for (var i = 0, l = it.list.length; i < l; i++) { }}<li class='item'>{{= it.list[i] }}</li>{{ } }}</ul></div>");

  window.noHtmlTemplate = function(data){ return {tag: "DIV",children:[{tag:"H1",cls:"header",text:data.header},{tag:"H2",cls:"header2",text:data.header2},{tag:"H3",cls:"header3",text:data.header3},{tag:"H4",cls:"header4",text:data.header4},{tag:"H5",cls:"header5",text:data.header5},{tag:"H6",cls:"header6",text:data.header6},{tag:"UL",cls:"list",children:data.list.reduce(function(p,item){p.push({tag:"LI",cls:"item",text:item}); return p;},[])}]}};

  window.jqote_tmpl = "<div><h1 class='header'><%= this.header %></h1><h2 class='header2'><%= this.header2 %></h2><h3 class='header3'><%= this.header3 %></h3><h4 class='header4'><%= this.header4 %></h4><h5 class='header5'><%= this.header5 %></h5><h6 class='header6'><%= this.header6 %></h6><ul class='list'><% for (var n = 0, l = this.list.length; n < l; n++) { %><li class='item'><%= this.list[n] %></li><% } %></ul></div>";

  window.jqote2 = $.jqotec(jqote_tmpl);

  $.addSnippet("test1", "<div><h1 class='header'>{header}</h1><h2 class='header2'>{header2}</h2><h3 class='header3'>{header3}</h3><h4 class='header4'>{header4}</h4><h5 class='header5'>{header5}</h5><h6 class='header6'>{header6}</h6><ul class='list'>{list[]}<li class='item'>{val}</li>{[]list}</ul></div>");

  window.BabaJS_Template = "<div><h1 class='header'><%= data.header %></h1><h2 class='header2'><%= data.header2 %></h2><h3 class='header3'><%= data.header3 %></h3><h4 class='header4'><%= data.header4 %></h4><h5 class='header5'><%= data.header5 %></h5><h6 class='header6'><%= data.header6 %></h6><ul class='list'><%LOOP for (var n = 0, l = data.list.length; n < l; n++) %><li class=\"item\"><%= data.list[n] %></li><%ENDLOOP%></ul></div>";
  BabaJS.addTemplate("babajs_tpl", window.BabaJS_Template);

</script>

Test runner

Ready to run.

Testing in
TestOps/sec
Mustache.js Template
var div = document.createElement('div');
div.innerHTML = Mustache.to_html(mustacheTemplate, sharedVariables);
 
ready
Resig Micro-Templating.
var div = document.createElement('div');
div.innerHTML = resigTemplate(sharedVariables);
ready
Creationix's Haml-js Template
var div = document.createElement('div');
div.innerHTML = hamlTemplate(sharedVariables);
ready
Jade Template
var div = document.createElement('div');
div.innerHTML = jade.render(jadeTemplate, {
 locals: sharedVariables,
 filename: 'test.js',
 cache: true
});
ready
JUP Template
var div = document.createElement('div');
div.innerHTML = JUP.html([sharedVariables], jupTemplate);
ready
Underscore.js Template
var div = document.createElement('div');
div.innerHTML = underscoreTemplate(sharedVariables);
ready
Eco Template
var div = document.createElement('div');
div.innerHTML = ecoTemplate(sharedVariables);
ready
jQuery Templates
$.tmpl(jQueryTemplate, sharedVariables);
ready
Handlebars.js
var div = document.createElement('div');
div.innerHTML = handlebarsTemplate(sharedVariables);
ready
doT.js
var div = document.createElement('div');
div.innerHTML = doTtemplate(sharedVariables);
ready
doU.js
var div = document.createElement('div');
div.innerHTML = doUtemplate(sharedVariables);
ready
jQote2 direct
var div = document.createElement('div');
div.innerHTML = jqote2.call(sharedVariables, 0, 0, [sharedVariables], jqote2);
ready
Orange-J
var div = document.createElement('div');
div.innerHTML = $.snippet("test1", sharedVariables);
ready
NoHtml
$(noHtmlTemplate(sharedVariables));
ready
jqml
jqml(jqmlTemplate);
ready
Native overoptimized
var div = document.createElement('div');
div.innerHTML = '<div><h1 class="header">'+sharedVariables.header+'</h1><h2 class="header2">'+sharedVariables.header2+'</h2><h3 class="header3">'+sharedVariables.header3+'</h3><h4 class="header4">'+sharedVariables.header4+'</h4><h5 class="header5">'+sharedVariables.header5+'</h5><h6 class="header6">'+sharedVariables.header6+'</h6><ul class="list"><li class="item">' + sharedVariables.list.join('</li><li class="item">') + '</li></ul></div>';
ready
JAK
var div = document.createElement('div');
div.innerHTML = jakTemplate.render(sharedVariables);
 
ready
BabaJS
var div = document.createElement('div');
div.innerHTML = BabaJS.generateHTML({templateName:"babajs_tpl"}, window.sharedVariables);
ready

Revisions

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