Definitive Handlebars precompilation benchmark (v4)

Revision 4 of this benchmark created by Chad Johnson on


Description

Internationalization testing.

Preparation HTML

<!-- Libraries -->
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="//s3.amazonaws.com/github/downloads/wycats/handlebars.js/handlebars-1.0.rc.1.min.js"></script>

<!-- Precompiled templates -->
<script type="text/javascript">
(function() {
  var template = Handlebars.template, templates = Handlebars.templates = Handlebars.templates || {};
templates['page_compiled_with_strings'] = template(function (Handlebars,depth0,helpers,partials,data) {
  helpers = helpers || Handlebars.helpers;
  var buffer = "", stack1, foundHelper, functionType="function", escapeExpression=this.escapeExpression;
  buffer += "<div><label>Name</label><input type=\"text\" /></div>\r\n<div><label>Address</label><input type=\"text\" /></div>\r\n<div><label>Phone</label><input type=\"text\" /></div>\r\n<div><label>DOB</label><input type=\"text\" /></div>\r\n<div><label>Age</label><input type=\"text\" /></div>\r\n<div><label>Weight</label><input type=\"text\" /></div>\r\n<div><label>Gender</label><input type=\"text\" /></div>\r\n<div><label>Password</label><input type=\"text\" /></div>\r\n<div><label>Confirm Password</label><input type=\"text\" /></div>\r\n<div><label>Social Security Number</label><input type=\"text\" /></div>\r\n<div><label>Driver's License Number</label><input type=\"text\" /></div>\r\n<div><label>Shoe Size</label><input type=\"text\" /></div>\r\n<div><label>Pet Name</label><input type=\"text\" /></div>\r\n<div><label>Favorite Color</label><input type=\"text\" /></div>\r\n<div><label>Favorite Movie</label><input type=\"text\" /></div>\r\n\r\n<div>Data 1: ";
  foundHelper = helpers.data1;
  if (foundHelper) { stack1 = foundHelper.call(depth0, {hash:{}}); }
  else { stack1 = depth0.data1; stack1 = typeof stack1 === functionType ? stack1() : stack1; }
  buffer += escapeExpression(stack1) + "</div>\r\n<div>Data 2: ";
  foundHelper = helpers.data2;
  if (foundHelper) { stack1 = foundHelper.call(depth0, {hash:{}}); }
  else { stack1 = depth0.data2; stack1 = typeof stack1 === functionType ? stack1() : stack1; }
  buffer += escapeExpression(stack1) + "</div>\r\n<div>Data 3: ";
  foundHelper = helpers.data3;
  if (foundHelper) { stack1 = foundHelper.call(depth0, {hash:{}}); }
  else { stack1 = depth0.data3; stack1 = typeof stack1 === functionType ? stack1() : stack1; }
  buffer += escapeExpression(stack1) + "</div>\r\n<div>Nested data 1: ";
  stack1 = depth0.nested_data;
  stack1 = stack1 == null || stack1 === false ? stack1 : stack1.data1;
  stack1 = typeof stack1 === functionType ? stack1() : stack1;
  buffer += escapeExpression(stack1) + "</div>\r\n<div>Nested data 2: ";
  stack1 = depth0.nested_data;
  stack1 = stack1 == null || stack1 === false ? stack1 : stack1.data2;
  stack1 = typeof stack1 === functionType ? stack1() : stack1;
  buffer += escapeExpression(stack1) + "</div>\r\n<div>Nested data 3: ";
  stack1 = depth0.nested_data;
  stack1 = stack1 == null || stack1 === false ? stack1 : stack1.data3;
  stack1 = typeof stack1 === functionType ? stack1() : stack1;
  buffer += escapeExpression(stack1) + "</div>";
  return buffer;});
})();


(function() {
  var template = Handlebars.template, templates = Handlebars.templates = Handlebars.templates || {};
templates['page_compiled'] = template(function (Handlebars,depth0,helpers,partials,data) {
  helpers = helpers || Handlebars.helpers;
  var buffer = "", stack1, foundHelper, helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, functionType="function";
  buffer += "<div><label>";
  foundHelper = helpers['t'];
  stack1 = foundHelper ? foundHelper.call(depth0, "name", {hash:{}}) : helperMissing.call(depth0, "t", "name", {hash:{}});
  buffer += escapeExpression(stack1) + "</label><input type=\"text\" /></div>\r\n<div><label>";
  foundHelper = helpers['t'];
  stack1 = foundHelper ? foundHelper.call(depth0, "address", {hash:{}}) : helperMissing.call(depth0, "t", "address", {hash:{}});
  buffer += escapeExpression(stack1) + "</label><input type=\"text\" /></div>\r\n<div><label>";
  foundHelper = helpers['t'];
  stack1 = foundHelper ? foundHelper.call(depth0, "phone", {hash:{}}) : helperMissing.call(depth0, "t", "phone", {hash:{}});
  buffer += escapeExpression(stack1) + "</label><input type=\"text\" /></div>\r\n<div><label>";
  foundHelper = helpers['t'];
  stack1 = foundHelper ? foundHelper.call(depth0, "dob", {hash:{}}) : helperMissing.call(depth0, "t", "dob", {hash:{}});
  buffer += escapeExpression(stack1) + "</label><input type=\"text\" /></div>\r\n<div><label>";
  foundHelper = helpers['t'];
  stack1 = foundHelper ? foundHelper.call(depth0, "age", {hash:{}}) : helperMissing.call(depth0, "t", "age", {hash:{}});
  buffer += escapeExpression(stack1) + "</label><input type=\"text\" /></div>\r\n<div><label>";
  foundHelper = helpers['t'];
  stack1 = foundHelper ? foundHelper.call(depth0, "weight", {hash:{}}) : helperMissing.call(depth0, "t", "weight", {hash:{}});
  buffer += escapeExpression(stack1) + "</label><input type=\"text\" /></div>\r\n<div><label>";
  foundHelper = helpers['t'];
  stack1 = foundHelper ? foundHelper.call(depth0, "gender", {hash:{}}) : helperMissing.call(depth0, "t", "gender", {hash:{}});
  buffer += escapeExpression(stack1) + "</label><input type=\"text\" /></div>\r\n<div><label>";
  foundHelper = helpers['t'];
  stack1 = foundHelper ? foundHelper.call(depth0, "password", {hash:{}}) : helperMissing.call(depth0, "t", "password", {hash:{}});
  buffer += escapeExpression(stack1) + "</label><input type=\"text\" /></div>\r\n<div><label>";
  foundHelper = helpers['t'];
  stack1 = foundHelper ? foundHelper.call(depth0, "confirm_password", {hash:{}}) : helperMissing.call(depth0, "t", "confirm_password", {hash:{}});
  buffer += escapeExpression(stack1) + "</label><input type=\"text\" /></div>\r\n<div><label>";
  foundHelper = helpers['t'];
  stack1 = foundHelper ? foundHelper.call(depth0, "social_security_number", {hash:{}}) : helperMissing.call(depth0, "t", "social_security_number", {hash:{}});
  buffer += escapeExpression(stack1) + "</label><input type=\"text\" /></div>\r\n<div><label>";
  foundHelper = helpers['t'];
  stack1 = foundHelper ? foundHelper.call(depth0, "drivers_licese_number", {hash:{}}) : helperMissing.call(depth0, "t", "drivers_licese_number", {hash:{}});
  buffer += escapeExpression(stack1) + "</label><input type=\"text\" /></div>\r\n<div><label>";
  foundHelper = helpers['t'];
  stack1 = foundHelper ? foundHelper.call(depth0, "shoe_size", {hash:{}}) : helperMissing.call(depth0, "t", "shoe_size", {hash:{}});
  buffer += escapeExpression(stack1) + "</label><input type=\"text\" /></div>\r\n<div><label>";
  foundHelper = helpers['t'];
  stack1 = foundHelper ? foundHelper.call(depth0, "pet_name", {hash:{}}) : helperMissing.call(depth0, "t", "pet_name", {hash:{}});
  buffer += escapeExpression(stack1) + "</label><input type=\"text\" /></div>\r\n<div><label>";
  foundHelper = helpers['t'];
  stack1 = foundHelper ? foundHelper.call(depth0, "favorite_color", {hash:{}}) : helperMissing.call(depth0, "t", "favorite_color", {hash:{}});
  buffer += escapeExpression(stack1) + "</label><input type=\"text\" /></div>\r\n<div><label>";
  foundHelper = helpers['t'];
  stack1 = foundHelper ? foundHelper.call(depth0, "favorite_movie", {hash:{}}) : helperMissing.call(depth0, "t", "favorite_movie", {hash:{}});
  buffer += escapeExpression(stack1) + "</label><input type=\"text\" /></div>\r\n\r\n<div>Data 1: ";
  foundHelper = helpers.data1;
  if (foundHelper) { stack1 = foundHelper.call(depth0, {hash:{}}); }
  else { stack1 = depth0.data1; stack1 = typeof stack1 === functionType ? stack1() : stack1; }
  buffer += escapeExpression(stack1) + "</div>\r\n<div>Data 2: ";
  foundHelper = helpers.data2;
  if (foundHelper) { stack1 = foundHelper.call(depth0, {hash:{}}); }
  else { stack1 = depth0.data2; stack1 = typeof stack1 === functionType ? stack1() : stack1; }
  buffer += escapeExpression(stack1) + "</div>\r\n<div>Data 3: ";
  foundHelper = helpers.data3;
  if (foundHelper) { stack1 = foundHelper.call(depth0, {hash:{}}); }
  else { stack1 = depth0.data3; stack1 = typeof stack1 === functionType ? stack1() : stack1; }
  buffer += escapeExpression(stack1) + "</div>\r\n<div>Nested data 1: ";
  stack1 = depth0.nested_data;
  stack1 = stack1 == null || stack1 === false ? stack1 : stack1.data1;
  stack1 = typeof stack1 === functionType ? stack1() : stack1;
  buffer += escapeExpression(stack1) + "</div>\r\n<div>Nested data 2: ";
  stack1 = depth0.nested_data;
  stack1 = stack1 == null || stack1 === false ? stack1 : stack1.data2;
  stack1 = typeof stack1 === functionType ? stack1() : stack1;
  buffer += escapeExpression(stack1) + "</div>\r\n<div>Nested data 3: ";
  stack1 = depth0.nested_data;
  stack1 = stack1 == null || stack1 === false ? stack1 : stack1.data3;
  stack1 = typeof stack1 === functionType ? stack1() : stack1;
  buffer += escapeExpression(stack1) + "</div>\r\n";
  return buffer;});
})();
</script>

<!-- Templates for "noncompiled" test -->
<script type="text/x-handlebars-template" id="page-template">
    <div><label>{{t "name"}}</label><input type="text" /></div>
    <div><label>{{t "address"}}</label><input type="text" /></div>
    <div><label>{{t "phone"}}</label><input type="text" /></div>
    <div><label>{{t "dob"}}</label><input type="text" /></div>
    <div><label>{{t "age"}}</label><input type="text" /></div>
    <div><label>{{t "weight"}}</label><input type="text" /></div>
    <div><label>{{t "gender"}}</label><input type="text" /></div>
    <div><label>{{t "password"}}</label><input type="text" /></div>
    <div><label>{{t "confirm_password"}}</label><input type="text" /></div>
    <div><label>{{t "social_security_number"}}</label><input type="text" /></div>
    <div><label>{{t "drivers_license_number"}}</label><input type="text" /></div>
    <div><label>{{t "shoe_size"}}</label><input type="text" /></div>
    <div><label>{{t "pet_name"}}</label><input type="text" /></div>
    <div><label>{{t "favorite_color"}}</label><input type="text" /></div>
    <div><label>{{t "favorite_movie"}}</label><input type="text" /></div>

    <div>Data 1: {{data1}}</div>
    <div>Data 2: {{data2}}</div>
    <div>Data 3: {{data3}}</div>
    <div>Nested data 1: {{nested_data.data1}}</div>
    <div>Nested data 2: {{nested_data.data2}}</div>
    <div>Nested data 3: {{nested_data.data3}}</div>
</script>

<script>
  var markup = $('#page-template').html();

  var LOCALE = {
      "name": "Name",
      "address": "Address",
      "phone": "Phone",
      "dob": "Date of Birth",
      "age": "Age",
      "weight": "Weight",
      "gender": "Gender",
      "password": "Password",
      "confirm_password": "Confirm Password",
      "social_security_number": "Social Security Number",
      "drivers_license_number": "Driver's License Number",
      "shoe_size": "Shoe Size",
      "pet_name": "Pet Name",
      "favorite_color": "Favorite Color",
      "favorite_movie": "Favorite Movie",
  };

  var data = {
      "data1": "value1",
      "data2": "value2",
      "data3": "value3",
      "nested_data": {
          "data1": "value1",
          "data2": "value2",
          "data3": "value3"
      }
  };

  Handlebars.registerHelper("t", function(qualifiedKey) {
      //var localizedString = new Function('return(LOCALE.' + qualifiedKey + ')')();

      //var localizedString = eval('LOCALE.' + qualifiedKey);

      var localizedString = LOCALE;
      var nestedKeys = qualifiedKey.split('.');
      for(var i = 0; i < nestedKeys.length; i++) {
        localizedString = localizedString[nestedKeys[i]];
      }

      return Handlebars.SafeString(localizedString);
  });
</script>

Test runner

Ready to run.

Testing in
TestOps/sec
noncompiled
// compile template
var pageTemplate = Handlebars.compile(markup);

// render template
var html = pageTemplate(data);
ready
precompiled
var pageTemplate = Handlebars.templates['page_compiled'];

// render template
var html = pageTemplate(data);
ready
precompiled with i18n strings in template
var pageTemplate = Handlebars.templates['page_compiled_with_strings'];

// render template
var html = pageTemplate(data);
ready

Revisions

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