JavaScript template language shootoff
JavaScript performance comparison
Info
A brief comparison of some JavaScript templating engines on a short template: 6 header tags, and 10 list items.
Note: When adding a new test, please ensure that your test returns the same HTML string (or equivalent DOM fragment) as the others.
Preparation code
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script src="http://documentcloud.github.com/underscore/underscore.js"></script>
<script src="http://github.com/janl/mustache.js/raw/master/mustache.js"></script>
<script src="http://terrainformatica.com/kite/kite.js"></script>
<script src="https://github.com/downloads/wycats/handlebars.js/handlebars-0.9.0.pre.4.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="https://github.com/jquery/jquery-tmpl/raw/master/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="http://github.com/aefxx/jQote2/raw/69b2053a13f5f180e696de9b3dba856a3c00678c/jquery.jqote2.js"></script>
<script src="http://embeddedjavascript.googlecode.com/files/ejs_0.9_alpha_1_production.js"></script>
<script src="http://github.com/pure/pure/raw/master/libs/pure.js"></script>
<div class="pure">
<h1 class='header'></h1>
<h2 class='header2'></h2>
<h3 class='header3'></h3>
<h4 class='header4'></h4>
<h5 class='header5'></h5>
<h6 class='header6'></h6>
<ul class='list'>
<li class='item'></li>
</ul>
</div>
<script src="https://github.com/douglascrockford/JSON-js/raw/master/json2.js"></script>
<script src="http://akdubya.github.com/dustjs/dist/dust-full-0.3.0.min.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>";
// note: exactly the same as the mustacheTemplate above.
window.kiteTemplate = "<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.kiteCompiledTemplate = kite(kiteTemplate);
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'>{{#each list}}<li class='item'>{{this}}</li>{{/each}}</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.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.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'>{{html header}}</h1><h2 class='header2'>{{html header2}}</h2><h3 class='header3'>{{html header3}}</h3><h4 class='header4'>{{html header4}}</h4><h5 class='header5'>{{html header5}}</h5><h6 class='header6'>{{html header6}}</h6><ul class='list'>{{each list}}<li class='item'>{{html $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.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);
window.ejs = new EJS({
text: micro
});
window.baseHtml = "<div><h1 class='header'></h1><h2 class='header2'></h2><h3 class='header3'></h3><h4 class='header4'></h4><h5 class='header5'></h5><h6 class='header6'></h6><ul class='list'><li class='item'></li></ul></div>";
window.pureTemplate = $p('div.pure').compile({
h1: 'header',
h2: 'header2',
h3: 'header3',
h4: 'header4',
h5: 'header5',
h6: 'header6',
li: {
'itm<-list': {
'.': 'itm'
}
}
});
window.hamlTemplate_2 = "%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.hamlCompiled = Haml.compile(hamlTemplate_2);
window.hamlOptimized = Haml.optimize(hamlCompiled);
dust.loadSource(dust.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'>{.}</li>{/list}</ul></div>", "dustTemplate"));
</script>
Preparation code output
Test runner
Warning! For accurate results, please disable Firebug before running the tests. (Why?)
Java applet disabled.
| Test | Ops/sec | |
|---|---|---|
Mustache.js Template |
|
pending… |
Resig Micro-Templating. |
|
pending… |
Creationix's Haml-js Template |
|
pending… |
Jade Template |
|
pending… |
Underscore.js Template |
|
pending… |
Eco Template |
|
pending… |
jQuery Templates |
|
pending… |
Handlebars.js |
|
pending… |
doT.js |
|
pending… |
doU.js |
|
pending… |
jQote2 direct |
|
pending… |
ejs |
|
pending… |
Pure |
|
pending… |
Creationix's Haml-js Template (compiled & optimized) |
|
pending… |
dust |
|
pending… |
KiTE |
|
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:
- Revision 1: published by Jeremy Ashkenas
- Revision 3: published by Jeremy Ashkenas
- Revision 6: published
- Revision 7: published by bradleymeck
- Revision 8: published
- Revision 9: published by Jeremy Ashkenas
- Revision 11: published by Sam Stephenson
- Revision 13: published by Sam Stephenson
- Revision 14: published by bradleymeck
- Revision 15: published by Jeremy Ashkenas
- Revision 17: published by Jeremy Ashkenas
- Revision 20: published by Sam Stephenson
- Revision 22: published by Jeremy Ashkenas
- Revision 25: published by Carlos Killpack
- Revision 28: published by aefxx
- Revision 30: published by GregWa
- Revision 32: published by Carlos Killpack
- Revision 33: published by Schuyler D
- Revision 42: published by Schuyler D
- Revision 44: published by Schuyler D
- Revision 45: published by Jeremy Ashkenas
- Revision 47: published by Paul Sadauskas
- Revision 48: published by Yehuda Katz
- Revision 52: published by Laura Doktorova
- Revision 53: published by Laura Doktorova
- Revision 55: published by Jacob Chapel
- Revision 56: published by Jacob Chapel
- Revision 57: published by Mic
- Revision 59: published by Jeremy Ashkenas
- Revision 62: published by Jacob Chapel
- Revision 63: published by Jeremy Ashkenas
- Revision 64: published
- Revision 67: published by Jeremy Ashkenas
- Revision 70: published
- Revision 73: published by Jeremy Ashkenas
- Revision 76: published by Michael Paul
- Revision 77: published by Heitor Salazar Baldelli
- Revision 78: published by aefxx
- Revision 79: published by aefxx
- Revision 80: published by Marijn
- Revision 81: published by Manu
- Revision 82: published
- Revision 83: published by Boris Moore
- Revision 84: published by Jörn Zaefferer
- Revision 85: published by tsvetomir
- Revision 88: published by VasiliyS
- Revision 89: published by AndrewF
- Revision 90: published by Atanas Korchev
- Revision 91: published
- Revision 92: published
- Revision 94: published by tsvetomir
- Revision 95: published by AndrewF
- Revision 96: published by AndrewF
- Revision 97: published by foo
- Revision 99: published by AndrewF
- Revision 100: published by pvande
- Revision 103: published by Andrew Petersen
- Revision 104: published
- Revision 105: published by Premasagar Rose
- Revision 106: published by tmpvar
- Revision 111: published by Premasagar Rose
- Revision 112: published by Jeremy Ashkenas
- Revision 113: published
- Revision 114: published by Johann Chiang
- Revision 115: published
- Revision 117: published
- Revision 118: published by AndrewF
- Revision 120: published
- Revision 121: published
- Revision 128: published
- Revision 131: published
- Revision 133: published by Joel Hughes
- Revision 135: published by Arxisos
- Revision 136: published by Murmeli
- Revision 137: published by Murmeli
- Revision 138: published
- Revision 139: published by QLeelulu
- Revision 142: published by QLeelulu
- Revision 143: published by QLeelulu
- Revision 144: published by Shaun
- Revision 146: published by Schuyler D
- Revision 153: published by Andrew Petersen
- Revision 154: published
- Revision 155: published
- Revision 156: published by Tim Farland
- Revision 157: published by Kevin Decker
- Revision 159: published by Lloyd Cotten
- Revision 160: published by Daniel Lindsley
- Revision 162: published by Esteban Corrales
- Revision 163: published by Boris Moore
- Revision 164: published
- Revision 165: published by ben
- Revision 166: published by ben
- Revision 168: published by Sacah
- Revision 172: published by gt
- Revision 173: published
- Revision 174: published by rwb
- Revision 175: published by Joel 'Rudenoise' Hughes
- Revision 177: published by payload
- Revision 179: published
- Revision 180: published
- Revision 181: published
- Revision 182: published
- Revision 183: published
- Revision 184: published
- Revision 185: published
- Revision 187: published by EB
- Revision 188: published
- Revision 189: published by Todd Anglin
- Revision 190: published
- Revision 191: published by Chris Kihneman
- Revision 192: published by Chris Kihneman
- Revision 193: published
- Revision 194: published
- Revision 195: published
- Revision 196: published
- Revision 197: published by flo
- Revision 198: published
- Revision 199: published
- Revision 200: published by Todd Anglin
- Revision 201: published by Laura Doktorova
- Revision 202: published
- Revision 204: published by Todd Anglin
- Revision 205: published by Dave Tonge
- Revision 207: published by Vijayakrishna
- Revision 208: published by Vijayakrishna
- Revision 209: published
- Revision 210: published by Refael Ackermann
- Revision 211: published by Nate Cavanaugh and last updated
- Revision 214: published by Laura Doktorova
- Revision 215: published
- Revision 217: published by Todd Anglin
- Revision 231: published
- Revision 233: published by Jaap Dunnebier
- Revision 234: published by Mihai Bazon and last updated
- Revision 243: published
- Revision 244: published by jsPop
- Revision 245: published by jsPop
- Revision 246: published
- Revision 247: published by Nate Cavanaugh
- Revision 249: published by Garrick
- Revision 250: published
- Revision 253: published
- Revision 254: published by Lance Pollard
- Revision 256: published by jsPop
- Revision 257: published
- Revision 258: published by jsPop
- Revision 259: published by jsPop
- Revision 261: published by Robert Oswald
- Revision 264: published by Chris Dickinson
- Revision 265: published by Chris Dickinson
- Revision 267: published
- Revision 268: published
- Revision 269: published
- Revision 271: published by Joshua Holbrook
- Revision 272: published
- Revision 273: published by Gabriel Farrell
- Revision 275: published
- Revision 277: published by Juri
- Revision 281: published by Kelly Miyashiro
- Revision 282: published by Michael Kessler
- Revision 283: published by Sebastian Tschan
- Revision 284: published by Michael Kessler
- Revision 285: published by Sebastian Tschan
- Revision 286: published by Todd Anglin
- Revision 287: published
- Revision 290: published
- Revision 291: published by Danny
- Revision 292: published by Chris Dickinson
- Revision 295: published by ali: removed cheating benchmarks
- Revision 296: published by Fabiano Nunes
- Revision 297: published
- Revision 298: published
- Revision 299: published
- Revision 300: published by nakamura_to
- Revision 303: published
- Revision 305: published by Attila
- Revision 306: published by nakamura_to
- Revision 308: published by mrchief
- Revision 309: published by Joshua T Kalis
- Revision 311: published by Dony
- Revision 312: published by redsquare
- Revision 314: published by Chris Dickinson
- Revision 315: published
- Revision 316: published by Jens Roland
- Revision 318: published by Jens and last updated
- Revision 319: published by Jens Roland
- Revision 320: published
- Revision 321: published
- Revision 323: published
- Revision 324: published
- Revision 325: published by Jeff Barczewski
- Revision 327: published
- Revision 333: published
- Revision 334: published
- Revision 335: published
- Revision 337: published by Marek
- Revision 338: published by Jakub
- Revision 339: published
- Revision 341: published
- Revision 342: published
- Revision 343: published by Keets
- Revision 344: published
- Revision 346: published
- Revision 348: published
- Revision 349: published
- Revision 350: published
- Revision 352: published by Grant Husbands
- Revision 353: published by [Now produces DOM nodes]
- Revision 354: published by [Added Twitter's Hogan]
- Revision 356: published by Ryan Funduk
- Revision 357: published by [Restored benchmarks that work]
- Revision 359: published by [Defeat jQuery cache]
- Revision 361: published
- Revision 363: published
- Revision 364: published by [Restored working benchmarks - please stop breaking things]
- Revision 365: published by Jarno Keskikangas
- Revision 366: published by Jarno Keskikangas
- Revision 369: published by Ryan Funduk
- Revision 370: published by RubaXa
- Revision 373: published
- Revision 374: published
- Revision 375: published by Vadim M. Baryshev
- Revision 377: published
- Revision 379: published
- Revision 380: published by Matt Robenolt and last updated
- Revision 381: published by hite
- Revision 382: published
- Revision 383: published
- Revision 384: published
- Revision 385: published
- Revision 386: published
- Revision 387: published by Juve
- Revision 388: published by Ronald Holshausen
- Revision 389: published by Brandon Satrom
- Revision 390: published by Brad Dunbar
- Revision 391: published
- Revision 392: published by Brad Dunbar
- Revision 393: published
- Revision 394: published by leodagdag
- Revision 395: published
- Revision 400: published by [jsRender won through incorrect output - removed]
- Revision 401: published by [jQuery was caching - now defeated]
- Revision 402: published
- Revision 404: published
- Revision 405: published by [Please stop restoring broken benchmarks]
- Revision 406: published
- Revision 407: published
- Revision 408: published
- Revision 409: published
- Revision 410: published
- Revision 411: published by [added JsRender, non-optimized API, correct output]
- Revision 412: published
- Revision 413: published
- Revision 414: published
- Revision 415: published
- Revision 416: published
- Revision 417: published
- Revision 418: published by Sergey Kononenko
- Revision 419: published
- Revision 420: published by Vincent Mac
- Revision 421: published
- Revision 422: published
- Revision 423: published
- Revision 425: published
- Revision 426: published by James O'Reilly
- Revision 427: published by [Restored benchmarks that actually run]
- Revision 428: published
- Revision 429: published
- Revision 430: published
- Revision 431: published by Marcus Greenwood
- Revision 432: published
- Revision 433: published
- Revision 437: published
- Revision 438: published by work
- Revision 439: published by work2
- Revision 440: published by work3
- Revision 441: published by Saabi
- Revision 442: published by TJ
- Revision 443: published by Saabi
- Revision 444: published by TJ
- Revision 445: published by Saabimeister
- Revision 447: published by RC
- Revision 449: published by Saabimeister
- Revision 452: published
- Revision 453: published by Andrey
- Revision 454: published
- Revision 455: published by Larry Davis
- Revision 456: published by [Corrected async dust.js] and last updated
0 comments