doT.js Template Engine: Source Code Analysis and Performance Optimization
The article analyzes doT.js, a compact 6 KB, dependency‑free JavaScript template engine that builds rendering functions via regex‑based code generation, avoids the costly with statement, caches compiled templates, and delivers superior performance in benchmarks compared with jQuery‑tmpl and other minimal engines, while noting its less intuitive syntax for complex conditionals.
Background: Front‑end rendering frameworks evolve from MVC to MVVM; lightweight templating is needed for simple data‑template rendering.
In Meituan Waimai practice, large data arrays share the same template, prompting use of a fast template engine.
doT.js is highlighted as a compact (≈200 lines, 6 KB) and high‑performance engine. The author performed a benchmark (100 items rendered 10 000 times) showing superior speed.
Key advantages of doT.js:
Small size, no third‑party dependencies.
Rich expression support.
Excellent performance.
Usage example:
<script type="text/html" id="tpl">
<div>
<a>name:{{= it.name}}</a>
<p>age:{{= it.age}}</p>
<p>hello:{{= it.sayHello() }}</p>
<select>
{{~ it.arr:item}}
<option {{?item.id == it.stringParams2}}selected{{?}} value="{{=item.id}}">
{{=item.text}}
</option>
{{~}}
</select>
</div>
</script>
<script>
$("#app").html(doT.template($("#tpl").html())({
name:'stringParams1',
stringParams1:'stringParams1_value',
stringParams2:1,
arr:[{id:0,text:'val1'},{id:1,text:'val2'}],
sayHello:function () { return this[this.name] }
}));
</script>Core source of doT.js builds a rendering function by stripping whitespace, escaping characters, and replacing template tags with JavaScript code, finally returning a new Function:
...
str = ("var out='" + (c.strip ? str.replace(... ) : str)
.replace(/'|\\/g, "\\$&")
.replace(c.interpolate || skip, function(m, code){ return cse.start + unescape(code,c.canReturnNull) + cse.end; })
// other replacements …
+ "';return out;");
try { return new Function(c.varname, str); } catch(e){ /* error handling */ }
...The engine relies heavily on regular‑expression replacement. The templateSettings object defines patterns for interpolation, encoding, conditionals, iteration, etc.
templateSettings: {
evaluate: /\{\{([\s\S]+?(\}?)+)\}\}/g,
interpolate: /\{\{=([\s\S]+?)\}\}/g,
encode: /\{\{!([\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
}Comparison with other engines (jQuery‑tmpl, tmpl) shows that doT.js avoids the costly with statement and caches compiled templates, leading to better performance.
Example of jQuery‑tmpl compilation (uses with and new Function):
function buildTmplFn( markup ) {
return new Function("jQuery","$item",
"var $=jQuery,call,__=[],$data=$item.data;" +
"with($data){__.push('" + /* compiled markup */ + "');}return __;");
}Removing with and adding explicit template caching improves speed, as demonstrated by the author’s benchmarks.
Another minimal engine “tmpl” (≈25 lines) also uses with and new Function; the author refactored it to eliminate with, achieving performance gains.
Conclusion: doT.js offers a lightweight, dependency‑free solution with fast rendering, but its syntax can be less intuitive for complex conditionals, and it does not support custom tags unlike some other engines.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Meituan Technology Team
Over 10,000 engineers powering China’s leading lifestyle services e‑commerce platform. Supporting hundreds of millions of consumers, millions of merchants across 2,000+ industries. This is the public channel for the tech teams behind Meituan, Dianping, Meituan Waimai, Meituan Select, and related services.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
