AngularJS vs Handlebars vs Mithril (v5)

Revision 5 of this benchmark created by Ben on


Preparation HTML

<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.14/angular.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/handlebars.js/3.0.0/handlebars.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/mithril/0.1.30/mithril.min.js"></script>

<!-- Angular -->
<div ng-app>
  Angular:
  <span ng-controller="Ctrl as c" id="angList">
    <span ng-repeat="item in c.data track by $index">{{item}}</span>
  </span>
</div>

<!-- Handlebars -->
<div id="hbapp"></div>
<script type="text/x-handlebars" id="hbtemplate">
  Handlebars:
  <span>
    {{#each data}}<span>{{this}}</span>{{/each}}
  </span>
</script>

<!-- Mithril -->
<div id="mithrilapp">
  Mithril: <span id="mithrilMountNode"></span>
</div>

<script>
  var Ctrl = function() {
    this.data = [];

    $(document).ready(function() {
      var ang_scope = $('#angList').scope();
      window.ANGclear = function() {
        ang_scope.data.splice(0);
        ang_scope.$digest();
      };
      window.ANGpush = function(data) {
        ang_scope.data.push(data);
        ang_scope.$digest();
      }
    });
  };

  var HBapp = { data: [] };
  $(document).ready(function() {
    var hbTmpl = Handlebars.compile(document.getElementById('hbtemplate').innerHTML);
    window.HBclear = function() {
      HBapp.data.splice(0);
      document.getElementById('hbapp').innerHTML = hbTmpl(HBapp);
    }
    window.HBpush = function(data) {
      HBapp.data.push(data);
      document.getElementById('hbapp').innerHTML = hbTmpl(HBapp);
    }
  });

  var MithrilData = [];
  var mithapp = {
    controller: function() {
      this.data = MithrilData;

      $(document).ready(function() {
        m.module(document.getElementById('mithrilMountNode'), mithapp);
        window.Mclear = function() {
          MithrilData.splice(0);
          m.redraw();
        }
        window.Mpush = function(data) {
          MithrilData.push(data);
          m.redraw();
        }
      });
    },
    view: function(ctrl) {
      return m('span', ctrl.data.map(function(datum) { return m('span', datum); }));
    }
  }
</script>

Test runner

Ready to run.

Testing in
TestOps/sec
Angular 10
ANGclear();
for (var i = 0; i < 10; i++)
  ANGpush(i + '|');
ready
Angular 100
ANGclear();
for (var i = 0; i < 100; i++)
  ANGpush(i + '|');
ready
Angular 500
ANGclear();
for (var i = 0; i < 500; i++)
  ANGpush(i + '|');
ready
Handlebars 10
HBclear();
for (var i = 0; i < 10; i++)
  HBpush(i + '|');
ready
Handlebars 100
HBclear();
for (var i = 0; i < 100; i++)
  HBpush(i + '|');
ready
Handlebars 500
HBclear();
for (var i = 0; i < 500; i++)
  HBpush(i + '|');
ready
Mithril 10
Mclear();
for (var i = 0; i < 10; i++)
  Mpush(i + '|');
ready
Mithril 100
Mclear();
for (var i = 0; i < 100; i++)
  Mpush(i + '|');
ready
Mithril 500
Mclear();
for (var i = 0; i < 500; i++)
  Mpush(i + '|');
ready

Revisions

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