Javascript templating shootoff (extended)

JavaScript performance comparison

Revision 38 of this test case created by John-David

Info

Many engines gathered across all revisions of the original shoot off.

DO NOT LINK TO RAW.GITHUB.COM -- It will NOT work in latest firefox versions

Please:

Libraries (in no particular order):

Preparation code

<!---------------------------------------->
<!-- EXTERNAL LIBRARIES HOSTED BY A CDN -->
<!---------------------------------------->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script src="http://cdn.kendostatic.com/2011.2.804/js/kendo.all.min.js"></script>
<script src="http://dl.dropbox.com/u/513327/jsconf/2012/documentcloud/underscore.js"></script>
<script src="http://dl.dropbox.com/u/513327/jsconf/2012/mod/lodash_template.js"></script>
<script>
var lodash = _.noConflict();
</script>

<!--------------------------->
<!-- DOM TEMPLATES         -->
<!--------------------------->
<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>
</div>

<script>
/****************************************
 MASTER TEMPLATE DATA
 ****************************************/

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

/****************************************
 TEMPLATE ENGINES NOT HOSTED BY A CDN (github)
 ****************************************/

//Please minify any hard included library and note the version.

// Dot 0.2.0
// Laura Doktorova https://github.com/olado/doT
(function(){function o(){var b={"&":"&#38;","<":"&#60;",">":"&#62;",'"':"&#34;","'":"&#39;","/":"&#47;"},a=/&(?!\\w+;)|<|>|"|'|\//g;return function(f){return f?f.toString().replace(a,function(g){return b[g]||g}):f}}function p(b,a,f){return(typeof a==="string"?a:a.toString()).replace(b.define||h,function(g,e,c,i){if(e.indexOf("def.")===0)e=e.substring(4);if(!(e in f))if(c===":")f[e]=i;else eval("def['"+e+"']="+i);return""}).replace(b.use||h,function(g,e){var c=eval(e);return c?p(b,c,f):c})}function l(b){return b.replace(/\\('|\\)/g,
"$1").replace(/[\r\t\n]/g," ")}var j={version:"0.2.0",templateSettings:{evaluate:/\{\{([\s\S]+?)\}\}/g,interpolate:/\{\{=([\s\S]+?)\}\}/g,encode:/\{\{!([\s\S]+?)\}\}/g,use:/\{\{#([\s\S]+?)\}\}/g,define:/\{\{##\s*([\w\.$]+)\s*(\:|=)([\s\S]+?)#\}\}/g,conditional:/\{\{\?(\?)?\s*([\s\S]*?)\s*\}\}/g,iterate:/\{\{~\s*(?:\}\}|([\s\S]+?)\s*\:\s*([\w$]+)\s*(?:\:\s*([\w$]+))?\s*\}\})/g,varname:"it",strip:true,append:true,selfcontained:false},template:undefined,compile:undefined},m=function(){return this||(0,eval)("this")}();
if(typeof module!=="undefined"&&module.exports)module.exports=j;else if(typeof define==="function"&&define.amd)define(function(){return j});else m.doT=j;m.encodeHTML=o();var q={append:{start:"'+(",end:")+'",startencode:"'+encodeHTML("},split:{start:"';out+=(",end:");out+='",startencode:"';out+=encodeHTML("}},h=/$^/;j.template=function(b,a,f){a=a||j.templateSettings;var g=a.append?q.append:q.split,e,c=0,i;if(a.use||a.define){var r=m.def;m.def=f||{};b=p(a,b,m.def);m.def=r}b=("var out='"+(a.strip?b.replace(/(^|\r|\n)\t* +| +\t*(\r|\n|$)/g,
" ").replace(/\r|\n|\t|\/\*[\s\S]*?\*\//g,""):b).replace(/'|\\/g,"\\$&").replace(a.interpolate||h,function(n,d){return g.start+l(d)+g.end}).replace(a.encode||h,function(n,d){e=true;return g.startencode+l(d)+g.end}).replace(a.conditional||h,function(n,d,k){return d?k?"';}else if("+l(k)+"){out+='":"';}else{out+='":k?"';if("+l(k)+"){out+='":"';}out+='"}).replace(a.iterate||h,function(n,d,k,s){if(!d)return"';} } out+='";c+=1;i=s||"i"+c;d=l(d);return"';var arr"+c+"="+d+";if(arr"+c+"){var "+k+","+i+"=-1,l"+
c+"=arr"+c+".length-1;while("+i+"<l"+c+"){"+k+"=arr"+c+"["+i+"+=1];out+='"}).replace(a.evaluate||h,function(n,d){return"';"+l(d)+"out+='"})+"';return out;").replace(/\n/g,"\\n").replace(/\t/g,"\\t").replace(/\r/g,"\\r").replace(/(\s|;|}|^|{)out\+='';/g,"$1").replace(/\+''/g,"").replace(/(\s|;|}|^|{)out\+=''\+/g,"$1out+=");if(e&&a.selfcontained)b="var encodeHTML=("+o.toString()+"());"+b;try{return new Function(a.varname,b)}catch(t){typeof console!=="undefined"&&console.log("Could not create a template function: "+
b);throw t;}};j.compile=function(b,a){return j.template(b,null,a)}})();

/********************************
  PRE-COMPILED TEMPLATES
 ********************************/

// Underscore
window.tpl.underscore = _.template("<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></div>");

// Underscore - no with
window.tpl.underscoreNoWith = _.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></div>", null, {variable: 'data'});

// Lo-Dash
window.tpl.lodash = lodash.template("<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></div>");

// Lo-Dash - no with
window.tpl.lodashNoWith = lodash.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></div>", null, {variable: 'data'});

// Kendo
window.tpl.kendo = kendo.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></div>", {useWithBlock:true});
 
window.tpl.kendo2 = kendo.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></div>", {useWithBlock:false});

//Dot
window.tpl.dot = 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></div>");

</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
Kendo UI
tpl.kendo(tpl.vars);
pending…
Kendo UI (no "with" block)
tpl.kendo2(tpl.vars);
pending…
Underscore
tpl.underscore(tpl.vars);
pending…
Underscore - (no "with" block)
tpl.underscoreNoWith(tpl.vars);
pending…
Lo-Dash
tpl.lodash(tpl.vars);
pending…
Lo-Dash - (no "with" block)
tpl.lodashNoWith(tpl.vars);
pending…
Dot 0.2.0
tpl.dot(tpl.vars);
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:

2 comments

Kit Cambridge commented :

FYI, linking to raw.github.com doesn't work in IE 9, either.

Add a comment