JavaScript template language shootoff (v898)

Revision 898 of this benchmark created by Eamon Nerbonne on


Preparation HTML

<!--Sample output:-->
<div id="good_node" style="display:none;">
    <div>
        <h1 class="Some text">Some text</h1>
        <h2 class="More text">More text</h2>
        <h3 title="Allows &quot;double quotes&quot;">Allows "double quotes"</h3>
        <h4 title="&amp; isn't &amp;amp;">&amp; isn't &amp;amp;</h4>
        <h5 title="&lt;escaped ok='true'&gt;">&lt;escaped ok='true'&gt;</h5>
        <h6 title="Bold text">Bold text</h6>
        <ul class="list">
            <li class="item">1 &lt;ok&gt;</li>
            <li class="item">2 &lt;ok&gt;</li>
            <li class="item">3 &lt;ok&gt;</li>
            <li class="item">4 &lt;ok&gt;</li>
            <li class="item">5 &lt;ok&gt;</li>
            <li class="item">6 &lt;ok&gt;</li>
            <li class="item">7 &lt;ok&gt;</li>
            <li class="item">8 &lt;ok&gt;</li>
            <li class="item">9 &lt;ok&gt;</li>
            <li class="item">10 &lt;ok&gt;</li>
        </ul>
    </div>
</div>
<div id="sink_node" style="display:none;"></div>
<script>
    var sink_node = document.getElementById('sink_node');
    var good_node = document.getElementById('good_node');
    function htmlencode(str) {
        return (
            document.createElement("i")
            .appendChild(
                document.createTextNode(str)
            ).parentNode.innerHTML
        );
    }
    function simplify_spaces(str) {
        return str.replace(/(^|>)\s+($|<)/g, '$1$2');
    }
    

    function jq_template(str) {
        var tmpl = $.template(null, str);
        return function (context) {
            return tmpl($, {
                data: context
            }).join("");
        };
    }
   

</script>

<!--External Template Definitions-->



<script type="text/x-template" id="underscoreTemplateText">
    <div>
        <h1 class="<%- data.h1 %>"><%- data.h1 %></h1>
        <h2 class="<%- data.h2 %>"><%- data.h2 %></h2>
        <h3 title="<%- data.h3 %>"><%- data.h3 %></h3>
        <h4 title="<%- data.h4 %>"><%- data.h4 %></h4>
        <h5 title="<%- data.h5 %>"><%- data.h5 %></h5>
        <h6 title="<%- data.h6 %>"><%- data.h6 %></h6>
        <ul class='list'>
            <% for (var i = 0, l = data.list.length; i < l; i++) { %>
            <li class='item'><%- data.list[i] %></li>
            <% } %>
        </ul>
    </div>
</script>


<script type="text/x-template" id="jQueryTemplateText">
    <div>
        <h1 class='${h1}'>${h1}</h1>
        <h2 class='${h2}'>${h2}</h2>
        <h3 title='${h3}'>${h3}</h3>
        <h4 title='${h4}'>${h4}</h4>
        <h5 title='${h5}'>${h5}</h5>
        <h6 title='${h6}'>${h6}</h6>
        <ul class='list'>
            {{each list}}
            <li class='item'>${$value}</li>
            {{/each}}
        </ul>
    </div>
</script>
<script type="text/x-template" id="mustacheTemplateText">
    <div>
        <h1 class='{{h1}}'>{{h1}}</h1>
        <h2 class='{{h2}}'>{{h2}}</h2>
        <h3 title='{{h3}}'>{{h3}}</h3>
        <h4 title='{{h4}}'>{{h4}}</h4>
        <h5 title='{{h5}}'>{{h5}}</h5>
        <h6 title='{{h6}}'>{{h6}}</h6>
        <ul class='list'>
            {{#list}}
            <li class='item'>{{.}}</li>
            {{/list}}
        </ul>
    </div>
</script>
<script type="text/x-template" id="handlebarsTemplateText">
    <div>
        <h1 class='{{h1}}'>{{h1}}</h1>
        <h2 class='{{h2}}'>{{h2}}</h2>
        <h3 title='{{h3}}'>{{h3}}</h3>
        <h4 title='{{h4}}'>{{h4}}</h4>
        <h5 title='{{h5}}'>{{h5}}</h5>
        <h6 title='{{h6}}'>{{h6}}</h6>
        <ul class='list'>
            {{#each list}}
            <li class='item'>{{.}}</li>
            {{/each}}
        </ul>
    </div>
</script>

<script src="https://code.jquery.com/jquery-2.0.3.min.js"></script>
<script src="https://documentcloud.github.com/underscore/underscore.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mustache.js/0.7.2/mustache.min.js"></script>
<script src="https://builds.handlebarsjs.com.s3.amazonaws.com/handlebars-v1.2.0.js"></script>
<script src="https://ajax.microsoft.com/ajax/jquery.templates/beta1/jquery.tmpl.min.js"></script>

<script>
    window.sharedVariables = {
        h1: "Some text",
        h2: "More text",
        h3: "Allows \"double quotes\"",
        h4: "& isn't &amp;",
        h5: "<escaped ok='true'>",
        h6: "Bold text",
        list: ['1 <ok>', '2 <ok>', '3 <ok>', '4 <ok>', '5 <ok>', '6 <ok>', '7 <ok>', '8 <ok>', '9 <ok>', '10 <ok>']
    };
    function getTemplate(id) { return document.getElementById(id).textContent; }

    var templates = {
        jQuery: jq_template(getTemplate("jQueryTemplateText")),
        Mustache: Mustache.compile(getTemplate("mustacheTemplateText")),
        Handlebars: Handlebars.compile(getTemplate("handlebarsTemplateText")),
        Underscore: _.template(getTemplate("underscoreTemplateText"), null, { variable: 'data' }),
    }

    function mkTest(template, name) {
        return function () {
            sink_node.setAttribute('data-generator', name);

            // what good is a template if you don't change data between passes?
            sharedVariables.h1 = "New Header " + String(Math.random() * 2000 | 0);

            sink_node.innerHTML = template(sharedVariables);
        };
    }
    var test = {};
    for (var name in templates) {
        test[name] = mkTest(templates[name], name);
    }

</script>

Setup

sink_node.innerHTML = 'wrong';

Teardown


    var sink_html = simplify_spaces(sink_node.innerHTML);
    var good_node_h1 = document.querySelector("#good_node h1");
    good_node_h1.className = sharedVariables.h1;
    good_node_h1.innerHTML ='';
    good_node_h1.appendChild(document.createTextNode(sharedVariables.h1));
    
    var good_html = simplify_spaces(good_node.innerHTML);
    
    
     
    if(sink_html !== good_html) {
      throw {
        generator: htmlencode(sink_node.getAttribute('data-generator')),
        wrong_output: htmlencode(sink_html),
        right_output: htmlencode(good_html)
      };
    }
    
  

Test runner

Ready to run.

Testing in
TestOps/sec
Handlebars Compiled Template
test.Handlebars();
ready
Underscore.js Template
test.Underscore();
ready
Mustache Compiled Template
test.Mustache();
ready

Revisions

You can edit these tests or add more tests to this page by appending /edit to the URL.