Angular VS Knockout VS Ember VS Backbone (v740)

Revision 740 of this benchmark created by Jelena on


Description

Comparison between Angular, Knockout and Ember. Added Backbone. Also with comparison of optimization during object creation.

Newest versions

Preparation HTML

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

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

<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.13/angular.min.js"></script>

<script>
  var Ctrl = function($scope){
    $scope.data = [];
  }
  angular.element(document).ready(function() {
    window.ANGAPP = {
      scope: $('#angList').scope(),
      push: function(data){
        this.scope.data.push(data);
      },
      clear: function(){
        this.scope.data = [];
        this.scope.$digest();
      }
    };
  });
</script> 

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

<script src="http://knockoutjs.com/downloads/knockout-3.0.0.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);
  };
  var KOunwrap = function(value){
    // Source: http://jsperf.com/ko-unwrapobservable/2
    return ('function'===typeof(value)) ? value(): value;
  };
</script>

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

<script src="http://builds.handlebarsjs.com.s3.amazonaws.com/handlebars.runtime-v1.3.0.js"></script>
<script src="http://builds.emberjs.com/tags/v1.4.0/ember.min.js"></script>

<script>
  EMapp = Ember.Application.create({
    rootElement: $('#emapp')
  });
  EMapp.data = Ember.A();
  
  EMclear = function () {
    EMapp.get('data').clear();
  };
  EMreset = function () {
    EMapp.set('data', Ember.A());
  };
  EMpush = function (data) {
    EMapp.get('data').pushObject(data);
  };
</script>

<!--Backbone-->
<script src="http://underscorejs.org/underscore-min.js"></script>
<script src="http://backbonejs.org/backbone-min.js"></script>

<div id="backboneapp">
  <h3>Backbone</h3>
  <span class="backbone-items"></span>
</div>

<script>
var backboneView = Backbone.View.extend({
  push: function(i) {
    this.$el.append(i);
  },
  clear: function() {
    this.$el.html('');
  }

});

window.BB = new backboneView({el: "#backboneapp .backbone-items"});
</script>

Test runner

Ready to run.

Testing in
TestOps/sec
Angular 500
ANGAPP.clear();
for (var i = 0; i < 500; i++)
  ANGAPP.push(i);
ANGAPP.scope.$digest();
ready
Angular 500 (mod)
ANGAPP.clear();
for (var i = 0; i < 500; i++)
  ANGAPP.push(i);
ANGAPP.scope.$digest();
ready
Knockout 500
KOclear();
for (var i = 0; i < 500; i++)
  KOpush(i);
ready
Knockout 500 (mod)
KOclear();
var list = ko.utils.unwrapObservable(KOData);
for (var i = 0; i < 500; i++)
  list.push(i);
KOData.valueHasMutated();
ready
Knockout 500 (unwrap mod)
KOclear();
var list = KOunwrap(KOData);
for (var i = 0; i < 500; i++)
  list.push(i);
KOData.valueHasMutated();
ready
Ember 500
EMclear();
for (var i = 0; i < 500; i++) {
  EMpush(i);
}
ready
Ember 500 (mod)
Ember.run(function() {
  EMclear();
  for (var i = 0; i < 500; i++) {
    EMpush(i);
  }
});
ready
Ember 500 (reset mod)
Ember.run(function() {
  EMreset();
  for (var i = 0; i < 500; i++) {
    EMpush(i);
  }
});
ready
Backbone
BB.clear();
for (var i = 0; i < 500; i++) {
  BB.push(i);
}
ready

Revisions

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