HTML Compilers (v2)

Revision 2 of this benchmark created by asd on


Preparation HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/jade/1.10.0/jade.min.js"></script>
<script>
var locals = {
  things: [
    { a: 'blah', b: 'halb' }
  , { a: 'clah', b: 'halc' }
  , { a: 'clah', b: 'halc' }
  , { a: 'blah', b: 'halb' }
  , { a: 'clah', b: 'halc' }
  , { a: 'clah', b: 'halc' }
  , { a: 'clah', b: 'halc' }
  , { a: 'blah', b: 'halb' }
  , { a: 'blah', b: 'halb' }
  , { a: 'clah', b: 'halc' }
  , { a: 'blah', b: 'halb' }
  ]
}

var _ENCODE_HTML_RULES = {
      '&': '&amp;'
    , '<': '&lt;'
    , '>': '&gt;'
    , '"': '&#34;'
    , "'": '&#39;'
    }
  , _MATCH_HTML = /[&<>\'"]/g;

function betterEscape(html){
  var result = String(html).replace(_MATCH_HTML, function(m) {
    return _ENCODE_HTML_RULES[m] || m;
  });
  if (result === '' + html) return html;
  else return result;
};

var jadeWithBetterEscape = {
  escape: betterEscape
};

function jadeJoin(locals, jade){
var buf = [];
var jade_mixins = {};
var jade_interp;
;var locals_for_with = (locals || {});(function (things, undefined) {
buf.push("<!DOCTYPE html><html><head><title>Fortunes</title></head><body><p>Interesting website</p>");
// iterate things
;(function(){
  var $$obj = things;
  if ('number' == typeof $$obj.length) {

    for (var $index = 0, $$l = $$obj.length; $index < $$l; $index++) {
      var thing = $$obj[$index];

buf.push("<p>" + (jade.escape(null == (jade_interp = thing.a) ? "" : jade_interp)) + "</p><p>" + (jade.escape(null == (jade_interp = thing.b) ? "" : jade_interp)) + "</p>");
    }

  } else {
    var $$l = 0;
    for (var $index in $$obj) {
      $$l++;      var thing = $$obj[$index];

buf.push("<p>" + (jade.escape(null == (jade_interp = thing.a) ? "" : jade_interp)) + "</p><p>" + (jade.escape(null == (jade_interp = thing.b) ? "" : jade_interp)) + "</p>");
    }

  }
}).call(this);

buf.push("</body></html>");}.call(this,"things" in locals_for_with?locals_for_with.things:typeof things!=="undefined"?things:undefined,"undefined" in locals_for_with?locals_for_with.undefined:typeof undefined!=="undefined"?undefined:undefined));;return buf.join("");
}

function jadeText(locals, jade){
var text = "";
var jade_mixins = {};
var jade_interp;
;var locals_for_with = (locals || {});(function (things, undefined) {
text += "<!DOCTYPE html><html><head><title>Fortunes</title></head><body><p>Interesting website</p>";
// iterate things
;(function(){
  var $$obj = things;
  if ('number' == typeof $$obj.length) {

    for (var $index = 0, $$l = $$obj.length; $index < $$l; $index++) {
      var thing = $$obj[$index];

text += "<p>" + (jade.escape(null == (jade_interp = thing.a) ? "" : jade_interp)) + "</p><p>" + (jade.escape(null == (jade_interp = thing.b) ? "" : jade_interp)) + "</p>";
    }

  } else {
    var $$l = 0;
    for (var $index in $$obj) {
      $$l++;      var thing = $$obj[$index];

text += "<p>" + (jade.escape(null == (jade_interp = thing.a) ? "" : jade_interp)) + "</p><p>" + (jade.escape(null == (jade_interp = thing.b) ? "" : jade_interp)) + "</p>";
    }

  }
}).call(this);

text += "</body></html>";}.call(this,"things" in locals_for_with?locals_for_with.things:typeof things!=="undefined"?things:undefined,"undefined" in locals_for_with?locals_for_with.undefined:typeof undefined!=="undefined"?undefined:undefined));;return text;
}

function jadeBetterForLoopJoin(locals, jade){
var buf = [];
var jade_mixins = {};
var jade_interp;
;var locals_for_with = (locals || {});(function (things, undefined) {
buf.push("<!DOCTYPE html><html><head><title>Fortunes</title></head><body><p>Interesting website</p>");
// iterate things
;(function(){
  var $$obj = things;

    for (var $index = 0, $$l = $$obj.length; $index < $$l; $index++) {
      var thing = $$obj[$index];

buf.push("<p>" + (jade.escape(null == (jade_interp = thing.a) ? "" : jade_interp)) + "</p><p>" + (jade.escape(null == (jade_interp = thing.b) ? "" : jade_interp)) + "</p>");
    }
}).call(this);

buf.push("</body></html>");}.call(this,"things" in locals_for_with?locals_for_with.things:typeof things!=="undefined"?things:undefined,"undefined" in locals_for_with?locals_for_with.undefined:typeof undefined!=="undefined"?undefined:undefined));;return buf.join("");
}

function jadeBetterForLoopText(locals, jade){
var text = "";
var jade_mixins = {};
var jade_interp;
;var locals_for_with = (locals || {});(function (things, undefined) {
text += "<!DOCTYPE html><html><head><title>Fortunes</title></head><body><p>Interesting website</p>";
// iterate things
;(function(){
  var $$obj = things;

    for (var $index = 0, $$l = $$obj.length; $index < $$l; $index++) {
      var thing = $$obj[$index];

text += "<p>" + (jade.escape(null == (jade_interp = thing.a) ? "" : jade_interp)) + "</p><p>" + (jade.escape(null == (jade_interp = thing.b) ? "" : jade_interp)) + "</p>";
    }
}).call(this);

text += "</body></html>";}.call(this,"things" in locals_for_with?locals_for_with.things:typeof things!=="undefined"?things:undefined,"undefined" in locals_for_with?locals_for_with.undefined:typeof undefined!=="undefined"?undefined:undefined));;return text;
}

function jadeInlineForLoopJoin(locals, jade){
var buf = [];
var jade_mixins = {};
var jade_interp;
;var locals_for_with = (locals || {});(function (things, undefined) {
buf.push("<!DOCTYPE html><html><head><title>Fortunes</title></head><body><p>Interesting website</p>");

// iterate things
  var $$obj = things;

    for (var $index = 0, $$l = $$obj.length; $index < $$l; $index++) {
      var thing = $$obj[$index];

buf.push("<p>" + (jade.escape(null == (jade_interp = thing.a) ? "" : jade_interp)) + "</p><p>" + (jade.escape(null == (jade_interp = thing.b) ? "" : jade_interp)) + "</p>");
    }

buf.push("</body></html>");}.call(this,"things" in locals_for_with?locals_for_with.things:typeof things!=="undefined"?things:undefined,"undefined" in locals_for_with?locals_for_with.undefined:typeof undefined!=="undefined"?undefined:undefined));;return buf.join("");
}

function jadeInlineForLoopText(locals, jade){
var text = "";
var jade_mixins = {};
var jade_interp;
;var locals_for_with = (locals || {});(function (things, undefined) {
text += "<!DOCTYPE html><html><head><title>Fortunes</title></head><body><p>Interesting website</p>";

// iterate things
  var $$obj = things;

    for (var $index = 0, $$l = $$obj.length; $index < $$l; $index++) {
      var thing = $$obj[$index];

text += "<p>" + (jade.escape(null == (jade_interp = thing.a) ? "" : jade_interp)) + "</p><p>" + (jade.escape(null == (jade_interp = thing.b) ? "" : jade_interp)) + "</p>";
    }

text += "</body></html>";}.call(this,"things" in locals_for_with?locals_for_with.things:typeof things!=="undefined"?things:undefined,"undefined" in locals_for_with?locals_for_with.undefined:typeof undefined!=="undefined"?undefined:undefined));;return text;
}

function jadeSelfJoin(locals, jade){
var buf = [];
var jade_mixins = {};
var jade_interp;
var self = locals || {};
buf.push("<!DOCTYPE html><html><head><title>Fortunes</title></head><body><p>Interesting website</p>");
// iterate self.things
;(function(){
  var $$obj = self.things;
  if ('number' == typeof $$obj.length) {

    for (var $index = 0, $$l = $$obj.length; $index < $$l; $index++) {
      var thing = $$obj[$index];

buf.push("<p>" + (jade.escape(null == (jade_interp = thing.a) ? "" : jade_interp)) + "</p><p>" + (jade.escape(null == (jade_interp = thing.b) ? "" : jade_interp)) + "</p>");
    }

  } else {
    var $$l = 0;
    for (var $index in $$obj) {
      $$l++;      var thing = $$obj[$index];

buf.push("<p>" + (jade.escape(null == (jade_interp = thing.a) ? "" : jade_interp)) + "</p><p>" + (jade.escape(null == (jade_interp = thing.b) ? "" : jade_interp)) + "</p>");
    }

  }
}).call(this);

buf.push("</body></html>");;return buf.join("");
}

function jadeSelfText(locals, jade){
var text = "";
var jade_mixins = {};
var jade_interp;
var self = locals || {};
text += "<!DOCTYPE html><html><head><title>Fortunes</title></head><body><p>Interesting website</p>";
// iterate self.things
;(function(){
  var $$obj = self.things;
  if ('number' == typeof $$obj.length) {

    for (var $index = 0, $$l = $$obj.length; $index < $$l; $index++) {
      var thing = $$obj[$index];

text += "<p>" + (jade.escape(null == (jade_interp = thing.a) ? "" : jade_interp)) + "</p><p>" + (jade.escape(null == (jade_interp = thing.b) ? "" : jade_interp)) + "</p>";
    }

  } else {
    var $$l = 0;
    for (var $index in $$obj) {
      $$l++;      var thing = $$obj[$index];

text += "<p>" + (jade.escape(null == (jade_interp = thing.a) ? "" : jade_interp)) + "</p><p>" + (jade.escape(null == (jade_interp = thing.b) ? "" : jade_interp)) + "</p>";
    }

  }
}).call(this);

text += "</body></html>";;return text;
}

function jadeSelfBetterForLoopJoin(locals, jade){
var buf = [];
var jade_mixins = {};
var jade_interp;
var self = locals || {};
buf.push("<!DOCTYPE html><html><head><title>Fortunes</title></head><body><p>Interesting website</p>");
// iterate self.things
;(function(){
  var $$obj = self.things;
    for (var $index = 0, $$l = $$obj.length; $index < $$l; $index++) {
      var thing = $$obj[$index];

buf.push("<p>" + (jade.escape(null == (jade_interp = thing.a) ? "" : jade_interp)) + "</p><p>" + (jade.escape(null == (jade_interp = thing.b) ? "" : jade_interp)) + "</p>");
    }
}).call(this);

buf.push("</body></html>");;return buf.join("");
}

function jadeSelfBetterForLoopText(locals, jade){
var text = "";
var jade_mixins = {};
var jade_interp;
var self = locals || {};
text += "<!DOCTYPE html><html><head><title>Fortunes</title></head><body><p>Interesting website</p>";
// iterate self.things
;(function(){
  var $$obj = self.things;
    for (var $index = 0, $$l = $$obj.length; $index < $$l; $index++) {
      var thing = $$obj[$index];

text += "<p>" + (jade.escape(null == (jade_interp = thing.a) ? "" : jade_interp)) + "</p><p>" + (jade.escape(null == (jade_interp = thing.b) ? "" : jade_interp)) + "</p>";
    }
}).call(this);

text += "</body></html>";;return text;
}

function jadeSelfInlineLoopJoin(locals, jade){
var buf = [];
var jade_mixins = {};
var jade_interp;
var self = locals || {};
buf.push("<!DOCTYPE html><html><head><title>Fortunes</title></head><body><p>Interesting website</p>");
// iterate self.things
  var $$obj = self.things;
    for (var $index = 0, $$l = $$obj.length; $index < $$l; $index++) {
      var thing = $$obj[$index];

buf.push("<p>" + (jade.escape(null == (jade_interp = thing.a) ? "" : jade_interp)) + "</p><p>" + (jade.escape(null == (jade_interp = thing.b) ? "" : jade_interp)) + "</p>");
    }

buf.push("</body></html>");;return buf.join("");
}

function jadeSelfInlineLoopText(locals, jade){
var text = "";
var jade_mixins = {};
var jade_interp;
var self = locals || {};
text += "<!DOCTYPE html><html><head><title>Fortunes</title></head><body><p>Interesting website</p>";
// iterate self.things
  var $$obj = self.things;
    for (var $index = 0, $$l = $$obj.length; $index < $$l; $index++) {
      var thing = $$obj[$index];

text += "<p>" + (jade.escape(null == (jade_interp = thing.a) ? "" : jade_interp)) + "</p><p>" + (jade.escape(null == (jade_interp = thing.b) ? "" : jade_interp)) + "</p>";
    }

text += "</body></html>";;return text;
}

function ejsOriginal(locals, escape, include, rethrow) {
   var __output = [];
    ;  function printThing (thing) { 
    ; __output.push("  <p>")
    ; __output.push(escape(thing.a))
    ; __output.push("</p>\n  <p>")
    ; __output.push(escape(thing.b))
    ; __output.push("</p>\n")
    ;  } 
    ; __output.push("\n<!DOCTYPE html>\n<html>\n  <head>\n    <title>Fortunes</title>\n  </head>\n  <body>\n    <p>Interesting website</p>\n    ")
    ;  for (var i = 0; i < locals.things.length; i ++) {
         printThing(locals.things[i])
       } 
    ; __output.push("  </body>\n</html>\n")
  return __output.join("");
}

function ejsNoMixin(locals, escape, include, rethrow) {
   var __output = [];
    ; __output.push("\n<!DOCTYPE html>\n<html>\n  <head>\n    <title>Fortunes</title>\n  </head>\n  <body>\n    <p>Interesting website</p>\n    ")
    ;  for (var i = 0; i < locals.things.length; i ++) {
          var thing = locals.things[i];
          ; __output.push("  <p>")
          ; __output.push(escape(thing.a))
          ; __output.push("</p>\n  <p>")
          ; __output.push(escape(thing.b))
          ; __output.push("</p>\n")
       } 
    ; __output.push("  </body>\n</html>\n")
  return __output.join("");
}

</script>

Test runner

Ready to run.

Testing in
TestOps/sec
Jade using joins
jadeJoin(locals, jadeWithBetterEscape)
ready
Jade using joins with a better for loop
jadeBetterForLoopJoin(locals, jadeWithBetterEscape)
ready
Jade using joins with an inline for loop
jadeInlineForLoopJoin(locals, jadeWithBetterEscape)
ready
Jade self using joins
jadeSelfJoin(locals, jadeWithBetterEscape)
ready
Jade self using joins with a better for loop
jadeSelfInlineLoopJoin(locals, jadeWithBetterEscape)
ready
Jade self using joins with an inline for loop
jadeSelfBetterForLoopJoin(locals, jadeWithBetterEscape)
ready
EJS no mixin
ejsNoMixin(locals, betterEscape)
ready
EJS with mixin
ejsOriginal(locals, betterEscape)
ready
Jade using text
jadeText(locals, jadeWithBetterEscape)
ready
Jade using text with a better for loop
jadeBetterForLoopText(locals, jadeWithBetterEscape)
ready
Jade using text with an inline for loop
jadeInlineForLoopText(locals, jadeWithBetterEscape)
ready
Jade self using text
jadeSelfText(locals, jadeWithBetterEscape)
ready
Jade self using text with a better for loop
jadeSelfInlineLoopText(locals, jadeWithBetterEscape)
ready
Jade self using text with an inline for loop
jadeSelfBetterForLoopText(locals, jadeWithBetterEscape)
ready

Revisions

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