Performance comparison of jQuery Template vs String append vs other methods for table

JavaScript performance comparison

Revision 62 of this test case created by Nguyen Trang Hong Bao

Info

To test performance of jQuery template for outputting 100 rows each with 15 columns where the columns have fields that can trigger events.

Preparation code

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="http://ajax.microsoft.com/ajax/jquery.templates/beta1/jquery.tmpl.js"></script>
<script src="http://documentcloud.github.com/underscore/underscore-min.js"></script>
<script src="http://github.com/mhevery/mustache.js/raw/dot-notation/mustache.js"></script>
<script src="http://github.com/pvande/Milk/raw/master/dist/v1.2.0/milk.js"></script>
<script src="https://raw.github.com/Shopify/batman/master/lib/dist/batman.min.js"></script>
<script src="https://raw.github.com/BorisMoore/jsrender/master/jsrender.js"></script>
<script src="http://cloud.github.com/downloads/wycats/handlebars.js/handlebars-1.0.0.beta.6.js" type="text/javascript"></script>
<script src="https://github.com/andyet/ICanHaz.js/raw/master/ICanHaz.min.js"></script>
<script src="http://cloud.github.com/downloads/SteveSanderson/knockout/knockout-2.1.0.js"></script>


<script type="text/javascript">
    $(function() {
        $('body').delegate('#table .edit a, #table .select a', 'click', function() {
            var $td = $(this).closest('td');
            $td.find('input, select').show();
            $td.find('a').hide();
        });
       
        $('body').delegate('#table .edit .cancel, $table .select .cancel', 'click', function() {
            var $td = $(this).closest('td');
            $td.find('input, select').hide();
            $td.find('a').show();
        });    
    });
       
        function DummyFunction() {
                var prefix = "Hello";
                var suffix = "Wolrd!";
                var greeting = prefix + " " + suffix;
                alert(greeting);
        }
       
</script>

<script type="text/x-jquery-tmpl" id="jqueryTmpl">
  <tr>
        <td>
                <td><input type="checkbox" value="${id}" /></td>
                <td>${name}</td>
                <td>${custName}</td>
                <td>${winlost}</td>
                <td>${turnover}</td>
                <td>${margin}</td>
                <td>${betcount}</td>
                <td><div class="ipViewLink" onclick="DummyFunction();">${ip}</div></td>
                <td>${hasData}</td>
                <td>${sporttypeId}</td>
                <td>${sporttypeName}</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>
        </tr>
</script>

<script id="jsrendertmpl" type="text/x-jsrender">
    {{for rows}}
    <tr>
      <td><input type = 'checkbox' value = '{{:id}}' /></td>
      <td>{{:name}}</td>
      <td>{{:custName}}</td>
      <td>{{:winlost}}</td>
      <td>{{:turnover}}</td>
      <td>{{:margin}}</td>
      <td>{{:betcount}}</td>
          <td><div class='ipViewLink' onclick='DummyFunction();'>{{:ip}}</div></td>
      <td>{{:hasData}}</td>
      <td>{{:sporttypeId}}</td>
      <td>{{:sporttypeName}}</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>
    </tr>
        {{/for}}
</script>

<script type="text/x-handlebars-template" id="handlebarsTmpl">
        {{#each rows}}
        {{#with this}}
        <tr>
      <td><input type = "checkbox" value = "{{id}}" /></td>
      <td>{{name}}</td>
      <td>{{custName}}</td>
      <td>{{winlost}}</td>
      <td>{{turnover}}</td>
      <td>{{margin}}</td>
      <td>{{betcount}}</td>
          <td><div class="ipViewLink" onclick="DummyFunction();">{{ip}}</div></td>
      <td>{{hasData}}</td>
      <td>{{sporttypeId}}</td>
      <td>{{sporttypeName}}</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>
    </tr>
        {{/with}}
        {{/each}}
       
</script>

<script type="text/html" id="icanhazTmpl">
        {{#rows}}
        <tr>
      <td><input type = "checkbox" value = "{{id}}" /></td>
      <td>{{name}}</td>
      <td>{{custName}}</td>
      <td>{{winlost}}</td>
      <td>{{turnover}}</td>
      <td>{{margin}}</td>
      <td>{{betcount}}</td>
          <td><div class="ipViewLink" onclick="DummyFunction();">{{ip}}</div></td>
      <td>{{hasData}}</td>
      <td>{{sporttypeId}}</td>
      <td>{{sporttypeName}}</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>
    </tr>
        {{/rows}}

</script>
 

<script>
  var data = [];
  var numberOfRow = 100;
  for (var i = 0; i < numberOfRow; i++) {
           var row = {
                        id: i,
                        name: 'punter' + i,
                        custName: 'andrew',
                        winlost: (i * 2.2).toFixed(2),
                        turnover: i,
                        margin: i + '%',
                        betcount: i,
                        ip: '127.127.127.127',
                        hasData: false,
                        sporttypeId: 1,
                        sporttypeName: 'Soccer'
           };  
           data.push(row);
  }
 
  $.template("precompiledJqueryTmpl", document.getElementById("jqueryTmpl").innerHTML);
 
  var underscoreTmpl = "\
    <%for(var i=0;i<rows.length;i++){%>\
    <%var row=rows[i];%> \
    <tr>\
      <td><input type = 'checkbox' value = '<%= row.id%>' /></td>\
      <td><%= row.name%></td>\
      <td><%= row.custName%></td>\
      <td><%= row.winlost%></td>\
      <td><%= row.turnover%></td>\
      <td><%= row.margin%></td>\
      <td><%= row.betcount%></td>\
          <td><div class='ipViewLink' onclick='DummyFunction();'><%= row.ip%></div></td>\
      <td><%= row.hasData%></td>\
      <td><%= row.sporttypeId%></td>\
      <td><%= row.sporttypeName%></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>\
    </tr ><%}%>"
;
       
        var mustacheTmpl="\
                {{#rows}}\
                <tr>\
                  <td><input type = 'checkbox' value = '{{id}}' /></td>\
                  <td>{{name}}</td>\
                  <td>{{custName}}</td>\
                  <td>{{winlost}}</td>\
                  <td>{{turnover}}</td>\
                  <td>{{margin}}</td>\
                  <td>{{betcount}}</td>\
                  <td><div class='ipViewLink' onclick='DummyFunction();'>{{ip}}</div></td>\
                  <td>{{hasData}}</td>\
                  <td>{{sporttypeId}}</td>\
                  <td>{{sporttypeId}}</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>\
                </tr >{{/rows}}"
;      
       
         var milkTmpl="\
                {{#rows}}\
                <tr>\
                  <td><input type = 'checkbox' value = '{{id}}' /> </td>\
                  <td>{{name}}</td>\
                  <td>{{custName}}</td>\
                  <td>{{winlost}}</td>\
                  <td>{{turnover}}</td>\
                  <td>{{margin}}</td>\
                  <td>{{betcount}}</td>\
                  <td><div class='ipViewLink' onclick='DummyFunction();'>{{ip}}</div></td>\
                  <td>{{hasData}}</td>\
                  <td>{{sporttypeId}}</td>\
                  <td>{{sporttypeName}}</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>\
                </tr >{{/rows}}"
;
       
        var jsRenderTmpl = $.templates( "#jsrendertmpl" );     
        var handlebarsTmpl = Handlebars.compile($("#handlebarsTmpl").html());
       
       
</script>
<script>
Benchmark.prototype.setup = function() {
    var numberOfRow = 100;
};
</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
JQueryTemplate
var html1 = $("#jqueryTmpl").tmpl(data);
pending…
PrecompiledJQueryTemplate
var html2 = $.tmpl("precompiledJqueryTmpl", data);
pending…
StringPaddingMethod
var s = [];
for (var i = 0; i < numberOfRow; i++) {
        var html3_1 = '<tr>\
                                <td><input type="checkbox" value="'
+ data[i].id + '" /></td>\
                                <td>'
+ data[i].name + '</td>\
                                <td>'
+ data[i].custName + '</td>\
                                <td>'
+ data[i].winlost + '</td>\
                                <td>'
+ data[i].turnover + '</td>\
                                <td>'
+ data[i].margin + '</td>\
                                <td>'
+ data[i].betcount + '</td>\
                                <td><div class="ipViewLink">'
+ data[i].ip + '</div></td>\
                                <td>'
+ data[i].hasData + '</td>\
                                <td>'
+ data[i].sporttypeId + '</td>\
                                <td>'
+ data[i].sporttypeName + '</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>\
                        </tr>'
;
        s.push(html3_1);                               
}
var html3_2 = s.join('');
pending…
Underscore.js
var html4 = _.template(underscoreTmpl, {rows: data});
pending…
Mustache.js
var html5 = Mustache.to_html(mustacheTmpl, {rows: data});  
pending…
MustacheMilk
Milk.render(milkTmpl, {rows: data});  
pending…
StringPaddingMethod02
var s = [];
for (var i = 0; i < numberOfRow; i++) {
        s.push('<tr>\
                                <td><input type="checkbox" value="'
+ data[i].id + '" /></td>\
                                <td>'
+ data[i].name + '</td>\
                                <td>'
+ data[i].custName + '</td>\
                                <td>'
+ data[i].winlost + '</td>\
                                <td>'
+ data[i].turnover + '</td>\
                                <td>'
+ data[i].margin + '</td>\
                                <td>'
+ data[i].betcount + '</td>\
                                <td><div class="ipViewLink">'
+ data[i].ip + '</div></td>\
                                <td>'
+ data[i].hasData + '</td>\
                                <td>'
+ data[i].sporttypeId + '</td>\
                                <td>'
+ data[i].sporttypeName + '</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>\
                        </tr>'
);                       
}
var html7 = s.join('');
 
pending…
Jsrender
var html8 = jsRenderTmpl.render({rows: data});
pending…
Handlebars.js
var html9 = handlebarsTmpl({rows: data});
pending…
ICanHaz.js
var html10 = ich.icanhazTmpl({rows: data});
pending…
StringPaddingMethod03
var s = [];
for (var i = 0; i < numberOfRow; i++) {
        s.push('<tr>');
        s.push('<td><input type="checkbox" value="' + data[i].id + '" /></td>');
        s.push('<td>' + data[i].name + '</td>');
        s.push('<td>' + data[i].custName + '</td>');
        s.push('<td>' + data[i].winlost + '</td>');
        s.push('<td>' + data[i].turnover + '</td>');
        s.push('<td>' + data[i].margin + '</td>');
        s.push('<td>' + data[i].betcount + '</td>');
        s.push('<td><div class="ipViewLink" onclick="DummyFunction();">' + data[i].ip + '</div></td>');
        s.push('<td>' + data[i].hasData + '</td>');
        s.push('<td>' + data[i].sporttypeId + '</td>');
        s.push('<td>' + data[i].sporttypeName + '</td>');
        s.push('<td class="edit">');
        s.push('<a>Edit</a>');
        s.push('<input style="display:none;" type="hidden" value="Blah" />');
        s.push('<input class="cancel" type="button" value="cancel" />');
        s.push('</td>');
        s.push('<td class="select">');
        s.push('<a>Select</a>');
        s.push('<select style="display:none;">');
        s.push('<option>0</option>');
        s.push('<option>1</option>');
        s.push('<option>2</option>');
        s.push('<option>3</option>');
        s.push('<option>4</option>');
        s.push('<option>5</option>');
        s.push('<option>6</option>');
        s.push('<option>7</option>');
        s.push('<option>8</option>');
        s.push('<option>9</option>');
        s.push('<option>10</option>');
        s.push('</select>');
        s.push('<input class="cancel" type="button" value="cancel" />');
        s.push('</td>');
        s.push('<td>More string</td>');
        s.push('<td>More string</td>');
        s.push('</tr>');                       
}
var html11 = s.join('');
 
pending…
StringPaddingMethod04
var s = [];
for (var i = 0; i < numberOfRow; i++) {
        s.push('<tr>\
                                <td><input type="checkbox" value="'
);
        s.push(data[i].id);
        s.push('" /></td>\
                                <td>'
);
        s.push(data[i].name);
        s.push('</td>\
                                <td>'
);
        s.push(data[i].custName);
        s.push('</td>\
                                <td>'
);
        s.push(data[i].winlost);
        s.push('</td>\
                                <td>'
);
        s.push(data[i].turnover);
        s.push('</td>\
                                <td>'
);
        s.push(data[i].margin);
        s.push('</td>\
                                <td>'
);
        s.push(data[i].betcount);
        s.push('</td>\
                                <td><div class="ipViewLink" onclick="DummyFunction();">'
);
        s.push(data[i].ip);
        s.push('</div></td>\
                                <td>'
);
        s.push(data[i].hasData);
        s.push('</td>\
                                <td>'
);
        s.push(data[i].sporttypeId);
        s.push('</td>\
                                <td>'
);
        s.push(data[i].sporttypeName);
        s.push('</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>\
                        </tr>'
);                       
}
var html12= s.join('');
pending…
StringConcat
var s = [];
var html3_1 = '';
for (var i = 0; i < numberOfRow; i++) {
        html3_1 += '<tr>\
                                        <td><input type="checkbox" value="'
+ data[i].id + '" /></td>\
                                        <td>'
+ data[i].name + '</td>\
                                        <td>'
+ data[i].custName + '</td>\
                                        <td>'
+ data[i].winlost + '</td>\
                                        <td>'
+ data[i].turnover + '</td>\
                                        <td>'
+ data[i].margin + '</td>\
                                        <td>'
+ data[i].betcount + '</td>\
                                        <td><div class="ipViewLink" onclick="DummyFunction();">'
+ data[i].ip + '</div></td>\
                                        <td>'
+ data[i].hasData + '</td>\
                                        <td>'
+ data[i].sporttypeId + '</td>\
                                        <td>'
+ data[i].sporttypeName + '</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>\
                                </tr>'
;        
}
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