JavaScript Templates Engines
A quick comparison/ benchmark between Hogan, Dust, doT and underscore
Presentation and Readability
Hogan.js
Developed by Twitter (same team as Bootstrap), use exactly the same syntax as Mustache, but more performant and more stuff available server side.
<h1>My name is {{ name }}</h1>
{{#i18n}}I saw {{ animals.otaries }} otaries and {{ animals.wapitis }} wapitis{{/i18n}}
{{#song}}
<div>{{ . }}<div>
{{/song}}
dust.js
Developed by LinkedIn as their main mobile front-end template engine. Really powerful, much more patterns available.
<h1>My name is {name}</h1>
{@i18n key="I saw {animals.otaries} otaries and {animals.wapitis} wapitis" /}
{#song}
<div>{.}</div>
{/song}
doT.js
Designed to be the fastest JS engine ever
<h1>My name is {{= it.name }}</h1>
{{= it.i18n('I saw %s otaries and %s wapitis', it.animals.otaries, it.animals.wapitis) }}
{{~ it.song :value:index }}
<div>{{= value }}</div>
{{~}}
underscore.js
Templating is a part of the underscore.js
utility library developed by Backbone Author, @jaskhenas. Goal is to mimic erb templates style in JavaScript
<h1>My name is <%= name %></h1>
<%= i18n('I saw %s otaries and %s wapitis', animals.otaries, animals.wapitis) %>
<% _.forEach(song, function(value, index) { %>
<div><%= value %><div>
<% }) %>
with
underscore without without the
with
statement: to enable the direct use of object properties without prefix ({{ name }}
and not{{ myOb.name }}
), underscore compile the template function inside awith
statement, setting the function scope within the data object. It's easier to read, but really known to have bad performances. To avoid that, you can define custom context object and pass it as the 3rd argument of _.template, ex:_.template('Hello {{ data.name }}', null, { variable: 'data' })
.
@see underscore.js#template
Subjectively
- I think
Hogan
has the most readable code. Very easy to guess, functions are expressed as blocks, curly braces syntax inherited from mustache is know now and easy to read dust
is quite readable, but once you want custom functions (and complex stuff), it's a completely own language, that needs a real learning curvedoT
begins to be very complex when doing complex stuff (array rendering is not that easy to guess)underscore
is almost literal JavaScript inside, which can be cool, but it's not really what we want from a template engine
Performance (compilation + rendering)
For 1000 rendering iterations:
Lib | compiling time | Avg. rendering | compiled size |
---|---|---|---|
Hogan | 2 ms | 0.022 ms | 513 chars. |
Dust | 15 ms | 0.019 ms | 582 chars. |
doT | 1 ms | 0.007 ms | 307 chars |
_ | 1 ms | 0.014 ms | 425 chars. |
_ (no with) | 1 ms | 0.009 ms | 421 chars. |
A real outbust from doT
, while underscore
seemed really performant too. But we're currently talking about microseconds, so it may not be really relevant unless you're developing a videogame, or an app with a lot of loops and on-the-fly rendering.
Any chance you can adapt your test to http://jsperf.com? ^^