JS templating benchmarks
JavaScript performance comparison
Info
Compare templating engines that generate html strings.
Preparation code
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="http://documentcloud.github.com/underscore/underscore-min.js"></script>
<script src="https://raw.github.com/janl/mustache.js/master/mustache.js"></script>
<script src="https://raw.github.com/BorisMoore/jsrender/master/jsrender.js"></script>
<script src="https://github.com/downloads/wycats/handlebars.js/handlebars.runtime-1.0.0.beta.6" type="text/javascript"></script>
<script type="text/javascript">
var rows = [];
for (var i = 0; i < 100; i++) {
var row = {
id: i,
firstName: 'john',
lastName: 'doe'
};
rows.push(row);
}
var underscoreTmpl = "\
<table>\
<%for(var i=0;i<rows.length;i++){%>\
<%var row=rows[i];%> \
<tr> \
<td> <input type = 'checkbox' value = '<%= row.id%>' /> </td>\
<td><%= row.firstname%> <%= row.lastname%></td> \
<td class = 'edit'> \
<a> Edit </a>\
<input style='display:none;' type='hidden' value='Blah' /> \
<input class = 'cancel' type = 'button' value = 'cancel' /> \
</td>\
<td class='select'>\
<a>Select</a> \
<select style = 'display:none;'> \
<option>0</option>\
<option>1</option> \
<option>2</option>\
<option>3</option> \
<option>4</option>\
<option>5</option> \
<option>6</option>\
<option>7</option> \
<option>8</option>\
<option>9</option> \
<option>10</option>\
</select> \
<input class = 'cancel' type = 'button' value = 'cancel' /> \
</td>\
<td>More string</td> \
<td>More string</td>\
<td>More string</td> \
<td>More string</td>\
<td>More string</td> \
<td>More string</td>\
</tr ><%}%>\
</table>";
var mustacheTmpl = "\
<table>\
{{#rows}}\
<tr> \
<td> <input type = 'checkbox' value = '{{id}}' /> </td>\
<td>{{firstname}} {{lastname}}</td> \
<td class = 'edit'> \
<a> Edit </a>\
<input style='display:none;' type='hidden' value='Blah' /> \
<input class = 'cancel' type = 'button' value = 'cancel' /> \
</td>\
<td class='select'>\
<a>Select</a> \
<select style = 'display:none;'> \
<option>0</option>\
<option>1</option> \
<option>2</option>\
<option>3</option> \
<option>4</option>\
<option>5</option> \
<option>6</option>\
<option>7</option> \
<option>8</option>\
<option>9</option> \
<option>10</option>\
</select> \
<input class = 'cancel' type = 'button' value = 'cancel' /> \
</td>\
<td>More string</td> \
<td>More string</td>\
<td>More string</td> \
<td>More string</td>\
<td>More string</td> \
<td>More string</td>\
</tr >{{/rows}}\
<table>";
var jsRenderTmpl = "\
<table>\
{{#each rows}}\
<tr> \
<td> <input type = 'checkbox' value = '{{=id}}' /> </td>\
<td>{{=firstname}} {{=lastname}}</td> \
<td class = 'edit'> \
<a> Edit </a>\
<input style='display:none;' type='hidden' value='Blah' /> \
<input class = 'cancel' type = 'button' value = 'cancel' /> \
</td>\
<td class='select'>\
<a>Select</a> \
<select style = 'display:none;'> \
<option>0</option>\
<option>1</option> \
<option>2</option>\
<option>3</option> \
<option>4</option>\
<option>5</option> \
<option>6</option>\
<option>7</option> \
<option>8</option>\
<option>9</option> \
<option>10</option>\
</select> \
<input class = 'cancel' type = 'button' value = 'cancel' /> \
</td>\
<td>More string</td> \
<td>More string</td>\
<td>More string</td> \
<td>More string</td>\
<td>More string</td> \
<td>More string</td>\
</tr >\
{{/each}}\
</table>";
$.template("compiledTemplate", jsRenderTmpl);
// Handlebars
(function() {
var template = Handlebars.template, templates = Handlebars.templates = Handlebars.templates || {};
templates['table'] = template(function (Handlebars,depth0,helpers,partials,data) {
helpers = helpers || Handlebars.helpers;
var buffer = "", stack1, tmp1, self=this, functionType="function", helperMissing=helpers.helperMissing, undef=void 0, escapeExpression=this.escapeExpression, blockHelperMissing=helpers.blockHelperMissing;
function program1(depth0,data) {
var buffer = "", stack1;
buffer += "\n<tr> \n <td> <input type = 'checkbox' value = '";
stack1 = helpers.id || depth0.id;
if(typeof stack1 === functionType) { stack1 = stack1.call(depth0, { hash: {} }); }
else if(stack1=== undef) { stack1 = helperMissing.call(depth0, "id", { hash: {} }); }
buffer += escapeExpression(stack1) + "' /> </td>\n <td>";
stack1 = helpers.firstname || depth0.firstname;
if(typeof stack1 === functionType) { stack1 = stack1.call(depth0, { hash: {} }); }
else if(stack1=== undef) { stack1 = helperMissing.call(depth0, "firstname", { hash: {} }); }
buffer += escapeExpression(stack1) + " ";
stack1 = helpers.lastname || depth0.lastname;
if(typeof stack1 === functionType) { stack1 = stack1.call(depth0, { hash: {} }); }
else if(stack1=== undef) { stack1 = helperMissing.call(depth0, "lastname", { hash: {} }); }
buffer += escapeExpression(stack1) + "</td> \n <td class = 'edit'> \n <a> Edit </a>\n <input style='display:none;' type='hidden' value='Blah' /> \n <input class = 'cancel' type = 'button' value = 'cancel' /> \n </td>\n <td class='select'>\n <a>Select</a> \n <select style = 'display:none;'> \n <option>0</option>\n <option>1</option> \n <option>2</option>\n <option>3</option> \n <option>4</option>\n <option>5</option> \n <option>6</option>\n <option>7</option> \n <option>8</option>\n <option>9</option> \n <option>10</option>\n </select> \n <input class = 'cancel' type = 'button' value = 'cancel' /> \n </td>\n <td>More string</td> \n <td>More string</td>\n <td>More string</td> \n <td>More string</td>\n <td>More string</td> \n <td>More string</td>\n</tr >";
return buffer;}
buffer += "<table>\n";
stack1 = helpers.rows || depth0.rows;
tmp1 = self.program(1, program1, data);
tmp1.hash = {};
tmp1.fn = tmp1;
tmp1.inverse = self.noop;
if(typeof stack1 === functionType) { stack1 = stack1.call(depth0, tmp1); }
else { stack1 = blockHelperMissing.call(depth0, stack1, tmp1); }
if(stack1 || stack1 === 0) { buffer += stack1; }
buffer += "\n<table>\n\n";
return buffer;});
})()
</script>
<script type="text/html" id="icanhazTmpl">
<table>
{{#rows}}
<tr>
<td><input type = "checkbox" value = "{{id}}" /></td>
<td>{{firstName}} {{lastName}}</td>
<td class="edit">
<a>Edit</a>
<input style="display:none;" type="hidden" value="Blah" />
<input class="cancel" type="button" value="cancel" />
</td>
<td class="select">
<a>Select</a>
<select style="display:none;">
<option> 0 < /option>
<option>1</option>
<option>2</option>
<option>3</option>
<option>4</option>
<option>5</option>
<option>6</option>
<option>7</option>
<option>8</option>
<option>9</option>
<option>10</option>
</select>
<input class="cancel" type="button" value="cancel" />
</td>
<td>More string</td>
<td>More string</td>
<td>More string</td>
<td>More string</td>
<td>More string</td>
<td>More string</td>
</tr>
{{/rows}}
</table>
</script>
Preparation code output
Test runner
Warning! For accurate results, please disable Firebug before running the tests. (Why?)
Java applet disabled.
| Test | Ops/sec | |
|---|---|---|
jsrender |
|
pending… |
jsrender compiled |
|
pending… |
underscore |
|
pending… |
mustache |
|
pending… |
Handlebars.js |
|
pending… |
You can edit these tests or add even more tests to this page by appending /edit to the URL.
0 comments