Handlebars vs Swig

JavaScript performance comparison

Revision 127 of this test case created by Sérgio Oliveira

Info

To test performance of Swig vs Handlebars for outputting 100 rows each with 10 columns where the columns have fields that can trigger events.

Both have precompiled templates for the best performance.

Preparation code

<script src="http://paularmstrong.github.io/swig/js/swig.min.js">
</script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/handlebars.js/1.3.0/handlebars.min.js" type="text/javascript"></script>
<script>
  var data = [];

  for (var i = 0; i < 100; i++) {
    var row = {
      id: i,
      firstName: 'john',
      lastName: 'doe'
    };

    data.push(row);
  }

!function(){var t=Handlebars.template,n=Handlebars.templates=Handlebars.templates||{};n.hbsTest=t(function(t,n,a,o,e){function i(t,n){var o,e="";return e+="\n",o=a["with"].call(t,t,{hash:{},inverse:d.noop,fn:d.program(2,s,n),data:n}),(o||0===o)&&(e+=o),e+="\n"}function s(t,n){var o,e,i="";return i+='\n< tr > < td > < input type = "checkbox"\n  value = "',(e=a.id)?o=e.call(t,{hash:{},data:n}):(e=t&&t.id,o=typeof e===p?e.call(t,{hash:{},data:n}):e),i+=r(o)+'" / > < /td>\n  <td>',(e=a.firstName)?o=e.call(t,{hash:{},data:n}):(e=t&&t.firstName,o=typeof e===p?e.call(t,{hash:{},data:n}):e),i+=r(o)+" ",(e=a.lastName)?o=e.call(t,{hash:{},data:n}):(e=t&&t.lastName,o=typeof e===p?e.call(t,{hash:{},data:n}):e),i+=r(o)+'</td > < td class = "edit" > < a > Edit < /a>\n    <input style="display:none;" type="hidden" value="Blah" / > < input class = "cancel"\n  type = "button"\n  value = "cancel" / > < /td>\n  <td class="select">\n      <a>Select</a > < select style = "display:none;" > < option > 0 < /option>\n        <option>1</option > < option > 2 < /option>\n        <option>3</option > < option > 4 < /option>\n        <option>5</option > < option > 6 < /option>\n        <option>7</option > < option > 8 < /option>\n        <option>9</option > < option > 10 < /option>\n       </select > < input class = "cancel"\n  type = "button"\n  value = "cancel" / > < /td>\n   <td>More string</td > < td > More string < /td>\n   <td>More string</td > < td > More string < /td>\n   <td>More string</td > < td > More string < /td>\n</tr >\n'}this.compilerInfo=[4,">= 1.0.0"],a=this.merge(a,t.helpers),e=e||{};var l,p="function",r=this.escapeExpression,d=this;return l=a.each.call(n,n&&n.rows,{hash:{},inverse:d.noop,fn:d.program(1,i,e),data:e}),l||0===l?l:""})}();

var swigtpl = function (_swig,_ctx,_filters,_utils,_fn) {
  var _ext = _swig.extensions,
    _output = "";
(function () {
  var __l = ((typeof _ctx.rows !== "undefined") ? ((typeof _ctx.rows !== "undefined") ? _ctx.rows : "") : ((typeof rows !== "undefined") ? rows : ""));
  if (!__l) { return; }
  _ctx.___loopcache = { loop: _ctx.loop, row: _ctx.row, __k: _ctx.__k };
  _ctx.loop = { first: false, index: 1, index0: 0, revindex: __l.length, revindex0: __l.length - 1, length: __l.length, last: false };
  _utils.each(__l, function (row, __k) {
    _ctx.row = row;
    _ctx.__k = __k;
    _ctx.loop.key = __k;
    _ctx.loop.first = (_ctx.loop.index0 === 0);
    _ctx.loop.last = (_ctx.loop.revindex0 === 0);
    _output += "\n<tr>\n  <td><input type=\"checkbox\" value=\"";
_output += _filters["e"](((typeof _ctx.row !== "undefined" && _ctx.row.id !== undefined) ? ((typeof _ctx.row !== "undefined" && _ctx.row.id !== undefined) ? _ctx.row.id : "") : ((typeof row !== "undefined" && row.id !== undefined) ? row.id : "")));
_output += "\" />< /td>\n  <td>";
_output += _filters["e"](((typeof _ctx.row !== "undefined" && _ctx.row.firstName !== undefined) ? ((typeof _ctx.row !== "undefined" && _ctx.row.firstName !== undefined) ? _ctx.row.firstName : "") : ((typeof row !== "undefined" && row.firstName !== undefined) ? row.firstName : "")));
_output += " ";
_output += _filters["e"](((typeof _ctx.row !== "undefined" && _ctx.row.lastName !== undefined) ? ((typeof _ctx.row !== "undefined" && _ctx.row.lastName !== undefined) ? _ctx.row.lastName : "") : ((typeof row !== "undefined" && row.lastName !== undefined) ? row.lastName : "")));
_output += "</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><option>2</option>\n      <option>3</option><option>4</option>\n      <option>5</option><option>6</option>\n      <option>7</option><option>8</option>\n      <option>9</option><option>10</option>\n    </select >\n    <input class=\"cancel\" type=\"button\" value=\"cancel\" />\n   </td>\n   <td>More string</td><td>More string</td>\n   <td>More string</td><td>More string</td>\n   <td>More string</td><td>More string</td>\n</tr>\n";
    _ctx.loop.index += 1; _ctx.loop.index0 += 1; _ctx.loop.revindex -= 1; _ctx.loop.revindex0 -= 1;
  });
  _ctx.loop = _ctx.___loopcache.loop;
  _ctx.row = _ctx.___loopcache.row;
  _ctx.__k = _ctx.___loopcache.__k;
})();

  return _output;

};
</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
swig.js precompiled

var html = swig.run(swigtpl, {
  rows: data
});
 
pending…
handlebars.js precompiled

var handlebarsTmpl = Handlebars.templates['hbsTest'];
var handlebarsTmpl = handlebarsTmpl({
  rows: data
});
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