Handlebars VS TemplateEngine

JavaScript performance comparison

Test case created by Jason Miller and last updated

Info

Handlebars.js (1.0.0 b6, current)

vs

TemplateEngine (whatever was current at the time)

Every 10 iterations, I have chosen to re-compile Handlebars' template, because in the real world there is more than one template in an app. Pre-compiling templates server-side is not an option for the purposes of this test (user-created templates). This means these tests assume the same template is being merged only 10 times.

Preparation code

<script src="http://cloud.github.com/downloads/wycats/handlebars.js/handlebars-1.0.0.beta.6.js?"></script>

<script src="http://html5man.com/jslibs/TemplateEngine.js?"></script>

<div id="base"></div>


<script id="template-handlebars" type="text/template"><![CDATA[
    <div class="foo1">
        <h2>{{title}}</h2>
        <h4>Iterating over an object:</h4>
        <ul>
            {{#each list}}
                <li>{{this}}</li>
            {{/each}}
        </ul>
        <h4>Iterating over an array:</h4>
        <ol>
            {{#each arr}}
                <li>{{this}}</li>
            {{/each}}
        </ol>
        <h4>Recursive nesting:</h4>
        <ul>
            {{#each nest1}}
                <li>
                    <ol>
                        {{#each this}}
                            <li>{{this}}</li>
                        {{/each}}
                    </ol>
                </li>
            {{/each}}
        </ul>
    </div>
]]></script>


<script id="template-templateengine" type="text/template"><![CDATA[
    <div class="foo1">
        <h2>{{title}}</h2>
        <h4>Iterating over an object:</h4>
        <ul>
            {{#each list}}
                <li>{{.}}</li>
            {{/each}}
        </ul>
        <h4>Iterating over an array:</h4>
        <ol>
            {{#each arr}}
                <li>{{.}}</li>
            {{/each}}
        </ol>
        <h4>Recursive nesting:</h4>
        <ul>
            {{#each nest1}}
                <li>
                    <ol>
                        {{#each .}}
                            <li>{{.}}</li>
                        {{/each}}
                    </ol>
                </li>
            {{/each}}
        </ul>
    </div>
]]></script>
 
<script>
Benchmark.prototype.setup = function() {
    /** NOTE: Handlebars does not support #each for Objects by default. We have to re-implement the each block helper to get that functionality back. The code below is a slightly modified version of the example from the Handlebars website. */
    Handlebars.registerHelper('each', function(context, options) {
        var ret = "";
        for(var i in context) {
            if (context.hasOwnProperty(i)) {
                ret = ret + options.fn(context[i]);
            }
        }
        return ret;
    });
   
    //----------------------------
   
    var n = document.getElementById('template-handlebars');
    var handlebarsTpl = (n.textContent || n.nodeValue || '').replace(/(^<\!\[CDATA\[|\]\]>$)/gm,'');
   
    n = document.getElementById('template-templateengine');
    var templateEngineTpl = (n.textContent || n.nodeValue || '').replace(/(^<\!\[CDATA\[|\]\]>$)/gm,'');
   
    var base = document.getElementById('base');
   
    var context = {
            title : "Template Standoff",
            list : {
                test : "test value",
                test2 : "test 2 value",
                test3 : "test 3 value",
            },
            arr : [
                "array value 1",
                "array value 2",
                "array value 3",
                "array value 4"
            ],
            nest1 : {
                foo : [
                    "nested level 2, item 1, child 1",
                    "nested level 2, item 1, child 2",
                    "nested level 2, item 1, child 3"
                ],
                foo2 : [
                    "nested level 2, item 2, child 1",
                    "nested level 2, item 2, child 2"
                ],
                foo3 : [
                    "nested level 2, item 3, child 1",
                    "nested level 2, item 3, child 2",
                    "nested level 2, item 3, child 3",
                    "nested level 2, item 3, child 4"
                    ]
            }
        };
   
    var template;
   
    var precompiled = Handlebars.compile(handlebarsTpl);
   
    var index = 0;
   
   
};
</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
Handlebars
index++;
template = Handlebars.compile(handlebarsTpl);
base.innerHTML = template(context);
pending…
Handlebars (pre-compiled)
index++;
if (index%10===0) {
  precompiled = Handlebars.compile(handlebarsTpl);
}
base.innerHTML = precompiled(context);
pending…
TemplateEngine
index++;
base.innerHTML = engine.template(templateEngineTpl, context);
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:

0 comments

Add a comment