jsPerf.app is an online JavaScript performance benchmark test runner & jsperf.com mirror. It is a complete rewrite in homage to the once excellent jsperf.com now with hopefully a more modern & maintainable codebase.
jsperf.com URLs are mirrored at the same path, e.g:
https://jsperf.com/negative-modulo/2
Can be accessed at:
https://jsperf.app/negative-modulo/2
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.
<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>
Ready to run.
Test | Ops/sec | |
---|---|---|
Mustache.js Template |
| ready |
Resig Micro-Templating. |
| ready |
Creationix's Haml-js Template |
| ready |
Jade Template |
| ready |
JUP Template |
| ready |
Underscore.js Template |
| ready |
Eco Template |
| ready |
jQuery Templates |
| ready |
Handlebars.js |
| ready |
doT.js |
| ready |
doU.js |
| ready |
jQote2 direct |
| ready |
Orange-J |
| ready |
NoHtml |
| ready |
jqml |
| ready |
Native overoptimized |
| ready |
JAK |
| ready |
BabaJS |
| ready |
You can edit these tests or add more tests to this page by appending /edit to the URL.