Angular VS Knockout VS Ember

JavaScript performance comparison

Revision 18 of this test case created

Info

I saw an unfair comparison between Angular, Knockout, ExtJS, and Backbone, and it made me mad. So I created this one.

Preparation code

<!-- Jquery -->
<script src="http://code.jquery.com/jquery-1.7.2.min.js"></script>

<!-- Angular -->
<div ng-app>
  Angular:
  <span ng-controller="Ctrl" id="angList"><span ng-repeat="item in data">{{item}}</span></span>
</div>

<script src="http://code.angularjs.org/angular-1.0.1.min.js"></script>

<script>
  var Ctrl = function($scope){
    $scope.data = [];
  }
 
  angular.element(document).ready(function() {
    var ang_scope = $('#angList').scope();
   
    window.ANGclear = function(){
      ang_scope.data.splice(0, ang_scope.data.length);
      ang_scope.$digest();
    };
    window.ANGpush = function(data){
      ang_scope.data.push(data);
      //ang_scope.$digest();
    };
  });
</script>



<!-- Knockout -->
<div id="koapp">
  Knockout:
  <span data-bind="foreach: data"><span data-bind="text: $data"></span></span>
</div>

<script src="http://cdnjs.cloudflare.com/ajax/libs/knockout/2.0.0/knockout-min.js"></script>

<script>
  var KOData = ko.observableArray();
  var KOviewmodel = {data: KOData};
 
  ko.applyBindings(KOviewmodel, document.getElementById('koapp'));
  var KOclear = function (){
    KOData.splice(0, KOData().length);
  };
  var KOpush = function (data){
    KOData.push(data);
  };
</script>


<!-- Ember -->

<div id="emapp">
  Ember:
  <script type="text/x-handlebars">
    <span>
      {{#each EMapp.data}}<span>{{this}}</span>{{/each}}
    </span>
  </script>
</div>

<script>
  var ENV = {EXTEND_PROTOTYPES: false};
</script>

<script src="https://github.com/downloads/wycats/handlebars.js/handlebars-1.0.0.beta.6.js"></script>
<script src="https://github.com/downloads/emberjs/ember.js/ember-1.0.pre.min.js"></script>

<script>
  EMapp = Ember.Application.create({
    rootElement: $('#emapp')
  });
  EMapp.data = [];
 
  EMclear = function () {
    EMapp.data = [];
  };
  EMpush = function (data) {
    EMapp.data.push(data);
  };
</script>

Preparation code output

Angular: {{item}}
Knockout:
Ember:

Test runner

Warning! For accurate results, please disable Firebug before running the tests. (Why?)

Java applet disabled.

Testing in unknown unknown
Test Ops/sec
Angular 10
ANGclear();
for (var i = 0; i < 10; i++)
  ANGpush("ngitem");
pending…
Knockout 10
KOclear();
for (var i = 0; i < 10; i++)
  KOpush("koitem");
pending…
Ember 10
EMclear();
Ember.beginPropertyChanges();
for (var i = 0; i < 10; i++)
{
  EMpush("emitem");
}
Ember.endPropertyChanges();
pending…
Angular 100
ANGclear();
for (var i = 0; i < 100; i++)
  ANGpush("ngitem");
pending…
Knockout 100
KOclear();
for (var i = 0; i < 100; i++)
  KOpush("koitem");
pending…
Ember 100
EMclear();
Ember.beginPropertyChanges();
for (var i = 0; i < 100; i++)
{
  EMpush("emitem");
}
Ember.endPropertyChanges();
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:

1 comment

Chris Nicola commented :

Not sure adding the .begin/endPropertyChanges calls keeps with the spirit of the benchmark. If you wanted to do it that way and new what you were generating in between you could just set the data once with all elements of the set generated in the loop in any of these examples.

In the end this is a benchmark that is intended to show the performance of repeatedly setting the two-way bound data values. In real world performance you may not be able to know when/where to put your UI update calls.

Add a comment