AngularJS vs KnockoutJS vs ModelViewJS (v77)

Revision 77 of this benchmark created on


Description

Testing performance of (multiple) subscribers/watchers and updating the ui (Angular.js, knockoutjs, ModelView.js 0.60)

Preparation HTML

<script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.3/angular.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/knockout/3.3.0/knockout-min.js"></script>
<script src="https://foo123.github.io/libs/modelview-0.64.min.js"></script>

<script>
  var Ctrl = function($scope) {
      $scope.data = "";
      $scope.numberofChanges1 = 0;
      $scope.numberofChanges2 = 0;
      $scope.numberofChanges3 = 0;
      $scope.numberofChanges4 = 0;
      $scope.numberofChanges5 = 0;
      $scope.numberofChanges6 = 0;
      $scope.numberofChanges7 = 0;
      $scope.numberofChanges8 = 0;
      $scope.numberofChanges9 = 0;
      $scope.numberofChanges10 = 0;
      $scope.$watch('data', function(a,b,c){
          $scope.numberofChanges1++;
      });
      $scope.$watch('data', function(a,b,c){
          $scope.numberofChanges2++;
      });
      $scope.$watch('data', function(a,b,c){
          $scope.numberofChanges3++;
      });
      $scope.$watch('data', function(a,b,c){
          $scope.numberofChanges4++;
      });
      $scope.$watch('data', function(a,b,c){
          $scope.numberofChanges5++;
      });
      $scope.$watch('data', function(a,b,c){
          $scope.numberofChanges6++;
      });
      $scope.$watch('data', function(a,b,c){
          $scope.numberofChanges7++;
      });
      $scope.$watch('data', function(a,b,c){
          $scope.numberofChanges8++;
      });
      $scope.$watch('data', function(a,b,c){
          $scope.numberofChanges9++;
      });
      $scope.$watch('data', function(a,b,c){
          $scope.numberofChanges10++;
      });
  } 
      
  angular.element(document).ready(function() {
    var ang_scope = $('#angList').scope();

    ANGclear = function() {
     ang_scope.data = "OMGOMGOMG";
    };
    ANGpush = function() {
     ang_scope.data += "OMGOMGOMG";
     ang_scope.$apply();
    };
  }); 
</script> 

<script>
  var KOData = ko.observable("");
  var KOUpdates1 = ko.observable(0);
  var KOUpdates2 = ko.observable(0);
  var KOUpdates3 = ko.observable(0);
  var KOUpdates4 = ko.observable(0);
  var KOUpdates5 = ko.observable(0);
  var KOUpdates6 = ko.observable(0);
  var KOUpdates7 = ko.observable(0);
  var KOUpdates8 = ko.observable(0);
  var KOUpdates9 = ko.observable(0);
  var KOUpdates10 = ko.observable(0);
  KOData.subscribe(function(){
      KOUpdates1(KOUpdates1() + 1);
  });
  KOData.subscribe(function(){
      KOUpdates2(KOUpdates2() + 1);
  });
  KOData.subscribe(function(){
      KOUpdates3(KOUpdates3() + 1);
  });
  KOData.subscribe(function(){
      KOUpdates4(KOUpdates4() + 1);
  });
  KOData.subscribe(function(){
      KOUpdates5(KOUpdates5() + 1);
  });
  KOData.subscribe(function(){
      KOUpdates6(KOUpdates6() + 1);
  });
  KOData.subscribe(function(){
      KOUpdates7(KOUpdates7() + 1);
  });
  KOData.subscribe(function(){
      KOUpdates8(KOUpdates8() + 1);
  });
  KOData.subscribe(function(){
      KOUpdates9(KOUpdates9() + 1);
  });
  KOData.subscribe(function(){
      KOUpdates10(KOUpdates10() + 1);
  });
  var KOviewmodel = {data: KOData, updates1: KOUpdates1, updates2: KOUpdates2, updates3: KOUpdates3, updates4: KOUpdates4, updates5: KOUpdates5, updates6: KOUpdates6, updates7: KOUpdates7, updates8: KOUpdates8, updates9: KOUpdates9, updates10: KOUpdates10};
  
  ko.applyBindings(KOviewmodel, document.getElementById('koapp'));
  var KOclear = function (){
    KOData("");
  };
  var KOpush = function (){
    var old = KOData()
    KOData(old += "OMGOMGOMG");
  };
</script>

<script>
    var MVModel = new ModelView.Model('model', {
        data: ""
        ,updates1: 0
        ,updates2: 0
        ,updates3: 0
        ,updates4: 0
        ,updates5: 0
        ,updates6: 0
        ,updates7: 0
        ,updates8: 0
        ,updates9: 0
        ,updates10: 0
    }),
    MVApp = new ModelView.View('view', MVModel).autobind(false).livebind('$(__KEY__)').bind(['change'], document.getElementById('mvapp'));
    
    var MVclear = function(){ MVModel.set('data', "", true); };  
    var MVpush = function(){ MVModel.set('data', MVModel.$data.data+"OMGOMGOMG", true); };

    MVModel.on('change', function(evt, data){
        if ( 'data' == data.key ) 
            MVModel.set('updates1', MVModel.$data.updates1+1, true);
    });
    MVModel.on('change', function(evt, data){
        if ( 'data' == data.key ) 
            MVModel.set('updates2', MVModel.$data.updates2+1, true);
    });
    MVModel.on('change', function(evt, data){
        if ( 'data' == data.key ) 
            MVModel.set('updates3', MVModel.$data.updates3+1, true);
    });
    MVModel.on('change', function(evt, data){
        if ( 'data' == data.key ) 
            MVModel.set('updates4', MVModel.$data.updates4+1, true);
    });
    MVModel.on('change', function(evt, data){
        if ( 'data' == data.key ) 
            MVModel.set('updates5', MVModel.$data.updates5+1, true);
    });
    MVModel.on('change', function(evt, data){
        if ( 'data' == data.key ) 
            MVModel.set('updates6', MVModel.$data.updates6+1, true);
    });
    MVModel.on('change', function(evt, data){
        if ( 'data' == data.key ) 
            MVModel.set('updates7', MVModel.$data.updates7+1, true);
    });
    MVModel.on('change', function(evt, data){
        if ( 'data' == data.key ) 
            MVModel.set('updates8', MVModel.$data.updates8+1, true);
    });
    MVModel.on('change', function(evt, data){
        if ( 'data' == data.key ) 
            MVModel.set('updates9', MVModel.$data.updates9+1, true);
    });
    MVModel.on('change', function(evt, data){
        if ( 'data' == data.key ) 
            MVModel.set('updates10', MVModel.$data.updates10+1, true);
    });
    MVApp.sync( );
</script>

<!-- Angular -->
<div style="width: 200px; height: 300px; overflow: hidden" ng-app>
  Angular:
  <span  ng-controller="Ctrl" id="angList">
<span> {{numberofChanges1}}</span>
<span> {{numberofChanges2}}</span>
<span> {{numberofChanges3}}</span>
<span> {{numberofChanges4}}</span>
<span> {{numberofChanges5}}</span>
<span> {{numberofChanges6}}</span>
<span> {{numberofChanges7}}</span>
<span> {{numberofChanges8}}</span>
<span> {{numberofChanges9}}</span>
<span> {{numberofChanges10}}</span>
<span> {{numberofChanges1}}</span>
<span> {{numberofChanges2}}</span>
<span> {{numberofChanges3}}</span>
<span> {{numberofChanges4}}</span>
<span> {{numberofChanges5}}</span>
<span> {{numberofChanges6}}</span>
<span> {{numberofChanges7}}</span>
<span> {{numberofChanges8}}</span>
<span> {{numberofChanges9}}</span>
<span> {{numberofChanges10}}</span>
<span> {{numberofChanges1}}</span>
<span> {{numberofChanges2}}</span>
<span> {{numberofChanges3}}</span>
<span> {{numberofChanges4}}</span>
<span> {{numberofChanges5}}</span>
<span> {{numberofChanges6}}</span>
<span> {{numberofChanges7}}</span>
<span> {{numberofChanges8}}</span>
<span> {{numberofChanges9}}</span>
<span> {{numberofChanges10}}</span>
<span> {{numberofChanges1}}</span>
<span> {{numberofChanges2}}</span>
<span> {{numberofChanges3}}</span>
<span> {{numberofChanges4}}</span>
<span> {{numberofChanges5}}</span>
<span> {{numberofChanges6}}</span>
<span> {{numberofChanges7}}</span>
<span> {{numberofChanges8}}</span>
<span> {{numberofChanges9}}</span>
<span> {{numberofChanges10}}</span>
<span> {{numberofChanges1}}</span>
<span> {{numberofChanges2}}</span>
<span> {{numberofChanges3}}</span>
<span> {{numberofChanges4}}</span>
<span> {{numberofChanges5}}</span>
<span> {{numberofChanges6}}</span>
<span> {{numberofChanges7}}</span>
<span> {{numberofChanges8}}</span>
<span> {{numberofChanges9}}</span>
<span> {{numberofChanges10}}</span>
<span> {{numberofChanges1}}</span>
<span> {{numberofChanges2}}</span>
<span> {{numberofChanges3}}</span>
<span> {{numberofChanges4}}</span>
<span> {{numberofChanges5}}</span>
<span> {{numberofChanges6}}</span>
<span> {{numberofChanges7}}</span>
<span> {{numberofChanges8}}</span>
<span> {{numberofChanges9}}</span>
<span> {{numberofChanges10}}</span>
<span> {{numberofChanges1}}</span>
<span> {{numberofChanges2}}</span>
<span> {{numberofChanges3}}</span>
<span> {{numberofChanges4}}</span>
<span> {{numberofChanges5}}</span>
<span> {{numberofChanges6}}</span>
<span> {{numberofChanges7}}</span>
<span> {{numberofChanges8}}</span>
<span> {{numberofChanges9}}</span>
<span> {{numberofChanges10}}</span>
<span> {{numberofChanges1}}</span>
<span> {{numberofChanges2}}</span>
<span> {{numberofChanges3}}</span>
<span> {{numberofChanges4}}</span>
<span> {{numberofChanges5}}</span>
<span> {{numberofChanges6}}</span>
<span> {{numberofChanges7}}</span>
<span> {{numberofChanges8}}</span>
<span> {{numberofChanges9}}</span>
<span> {{numberofChanges10}}</span>
<span> {{numberofChanges1}}</span>
<span> {{numberofChanges2}}</span>
<span> {{numberofChanges3}}</span>
<span> {{numberofChanges4}}</span>
<span> {{numberofChanges5}}</span>
<span> {{numberofChanges6}}</span>
<span> {{numberofChanges7}}</span>
<span> {{numberofChanges8}}</span>
<span> {{numberofChanges9}}</span>
<span> {{numberofChanges10}}</span>
<span> {{numberofChanges1}}</span>
<span> {{numberofChanges2}}</span>
<span> {{numberofChanges3}}</span>
<span> {{numberofChanges4}}</span>
<span> {{numberofChanges5}}</span>
<span> {{numberofChanges6}}</span>
<span> {{numberofChanges7}}</span>
<span> {{numberofChanges8}}</span>
<span> {{numberofChanges9}}</span>
<span> {{numberofChanges10}}</span>
    AngularTestArea Data: {{data}} 
  </span>
</div>

<!-- Knockout -->
<div style="width: 200px; height: 300px; overflow: hidden" id="koapp">
  Knockout: 
  <span>
    KnockoutTestArea Subscriber Updates: <span data-bind="text: data"></span>
<span data-bind="text: updates1"></span>
<span data-bind="text: updates1"></span>
<span data-bind="text: updates1"></span>
<span data-bind="text: updates1"></span>
<span data-bind="text: updates1"></span>
<span data-bind="text: updates1"></span>
<span data-bind="text: updates1"></span>
<span data-bind="text: updates1"></span>
<span data-bind="text: updates1"></span>
<span data-bind="text: updates1"></span>
<span data-bind="text: updates2"></span>
<span data-bind="text: updates2"></span>
<span data-bind="text: updates2"></span>
<span data-bind="text: updates2"></span>
<span data-bind="text: updates2"></span>
<span data-bind="text: updates2"></span>
<span data-bind="text: updates2"></span>
<span data-bind="text: updates2"></span>
<span data-bind="text: updates2"></span>
<span data-bind="text: updates2"></span>
<span data-bind="text: updates3"></span>
<span data-bind="text: updates3"></span>
<span data-bind="text: updates3"></span>
<span data-bind="text: updates3"></span>
<span data-bind="text: updates3"></span>
<span data-bind="text: updates3"></span>
<span data-bind="text: updates3"></span>
<span data-bind="text: updates3"></span>
<span data-bind="text: updates3"></span>
<span data-bind="text: updates3"></span> 
<span data-bind="text: updates4"></span>
<span data-bind="text: updates4"></span>
<span data-bind="text: updates4"></span>
<span data-bind="text: updates4"></span>
<span data-bind="text: updates4"></span>
<span data-bind="text: updates4"></span>
<span data-bind="text: updates4"></span>
<span data-bind="text: updates4"></span>
<span data-bind="text: updates4"></span>
<span data-bind="text: updates4"></span>
<span data-bind="text: updates5"></span>
<span data-bind="text: updates5"></span>
<span data-bind="text: updates5"></span>
<span data-bind="text: updates5"></span>
<span data-bind="text: updates5"></span>
<span data-bind="text: updates5"></span>
<span data-bind="text: updates5"></span>
<span data-bind="text: updates5"></span>
<span data-bind="text: updates5"></span>
<span data-bind="text: updates5"></span>
<span data-bind="text: updates6"></span>
<span data-bind="text: updates6"></span>
<span data-bind="text: updates6"></span>
<span data-bind="text: updates6"></span>
<span data-bind="text: updates6"></span>
<span data-bind="text: updates6"></span>
<span data-bind="text: updates6"></span>
<span data-bind="text: updates6"></span>
<span data-bind="text: updates6"></span>
<span data-bind="text: updates6"></span>
<span data-bind="text: updates7"></span>
<span data-bind="text: updates7"></span>
<span data-bind="text: updates7"></span>
<span data-bind="text: updates7"></span>
<span data-bind="text: updates7"></span>
<span data-bind="text: updates7"></span>
<span data-bind="text: updates7"></span>
<span data-bind="text: updates7"></span>
<span data-bind="text: updates7"></span>
<span data-bind="text: updates7"></span>
<span data-bind="text: updates8"></span>
<span data-bind="text: updates8"></span>
<span data-bind="text: updates8"></span>
<span data-bind="text: updates8"></span>
<span data-bind="text: updates8"></span>
<span data-bind="text: updates8"></span>
<span data-bind="text: updates8"></span>
<span data-bind="text: updates8"></span>
<span data-bind="text: updates8"></span>
<span data-bind="text: updates8"></span>
<span data-bind="text: updates9"></span>
<span data-bind="text: updates9"></span>
<span data-bind="text: updates9"></span>
<span data-bind="text: updates9"></span>
<span data-bind="text: updates9"></span>
<span data-bind="text: updates9"></span>
<span data-bind="text: updates9"></span>
<span data-bind="text: updates9"></span>
<span data-bind="text: updates9"></span>
<span data-bind="text: updates9"></span>
<span data-bind="text: updates10"></span>
<span data-bind="text: updates10"></span>
<span data-bind="text: updates10"></span>
<span data-bind="text: updates10"></span>
<span data-bind="text: updates10"></span>
<span data-bind="text: updates10"></span>
<span data-bind="text: updates10"></span>
<span data-bind="text: updates10"></span>
<span data-bind="text: updates10"></span>
<span data-bind="text: updates10"></span>
  </span>
</div>

<!-- ModelView -->
<div style="width: 200px; height: 300px; overflow: hidden" id="mvapp">
  ModelView: 
  <span>
    ModelViewTestArea Subscriber Updates: $(data)
<span>$(updates1)</span>
<span>$(updates1)</span>
<span>$(updates1)</span>
<span>$(updates1)</span>
<span>$(updates1)</span>
<span>$(updates1)</span>
<span>$(updates1)</span>
<span>$(updates1)</span>
<span>$(updates1)</span>
<span>$(updates1)</span>
<span>$(updates2)</span>
<span>$(updates2)</span>
<span>$(updates2)</span>
<span>$(updates2)</span>
<span>$(updates2)</span>
<span>$(updates2)</span>
<span>$(updates2)</span>
<span>$(updates2)</span>
<span>$(updates2)</span>
<span>$(updates2)</span>
<span>$(updates3)</span>
<span>$(updates3)</span>
<span>$(updates3)</span>
<span>$(updates3)</span>
<span>$(updates3)</span>
<span>$(updates3)</span>
<span>$(updates3)</span>
<span>$(updates3)</span>
<span>$(updates3)</span>
<span>$(updates3)</span>
<span>$(updates4)</span>
<span>$(updates4)</span>
<span>$(updates4)</span>
<span>$(updates4)</span>
<span>$(updates4)</span>
<span>$(updates4)</span>
<span>$(updates4)</span>
<span>$(updates4)</span>
<span>$(updates4)</span>
<span>$(updates4)</span>
<span>$(updates5)</span>
<span>$(updates5)</span>
<span>$(updates5)</span>
<span>$(updates5)</span>
<span>$(updates5)</span>
<span>$(updates5)</span>
<span>$(updates5)</span>
<span>$(updates5)</span>
<span>$(updates5)</span>
<span>$(updates5)</span>
<span>$(updates6)</span>
<span>$(updates6)</span>
<span>$(updates6)</span>
<span>$(updates6)</span>
<span>$(updates6)</span>
<span>$(updates6)</span>
<span>$(updates6)</span>
<span>$(updates6)</span>
<span>$(updates6)</span>
<span>$(updates6)</span>
<span>$(updates7)</span>
<span>$(updates7)</span>
<span>$(updates7)</span>
<span>$(updates7)</span>
<span>$(updates7)</span>
<span>$(updates7)</span>
<span>$(updates7)</span>
<span>$(updates7)</span>
<span>$(updates7)</span>
<span>$(updates7)</span>
<span>$(updates8)</span>
<span>$(updates8)</span>
<span>$(updates8)</span>
<span>$(updates8)</span>
<span>$(updates8)</span>
<span>$(updates8)</span>
<span>$(updates8)</span>
<span>$(updates8)</span>
<span>$(updates8)</span>
<span>$(updates8)</span>
<span>$(updates9)</span>
<span>$(updates9)</span>
<span>$(updates9)</span>
<span>$(updates9)</span>
<span>$(updates9)</span>
<span>$(updates9)</span>
<span>$(updates9)</span>
<span>$(updates9)</span>
<span>$(updates9)</span>
<span>$(updates9)</span>
<span>$(updates10)</span>
<span>$(updates10)</span>
<span>$(updates10)</span>
<span>$(updates10)</span>
<span>$(updates10)</span>
<span>$(updates10)</span>
<span>$(updates10)</span>
<span>$(updates10)</span>
<span>$(updates10)</span>
<span>$(updates10)</span>
  </span>
</div>

Test runner

Ready to run.

Testing in
TestOps/sec
Angular 10
ANGclear();
for (var i = 0; i < 10; i++) {
  ANGpush();
}
ready
Knockout 10
KOclear();
for (var i = 0; i < 10; i++) {
  KOpush();
}
ready
ModelView 10
MVclear();
for (var i = 0; i < 10; i++) {
  MVpush();
}
ready
Angular 100
ANGclear();
for (var i = 0; i < 100; i++) {
  ANGpush();
}
ready
Knockout 100
KOclear();
for (var i = 0; i < 100; i++) {
  KOpush();
}
ready
ModelView 100
MVclear();
for (var i = 0; i < 100; i++) {
  MVpush();
}
ready
Angular 1000
ANGclear();
for (var i = 0; i < 1000; i++) {
  ANGpush();
}
ready
Knockout 1000
KOclear();
for (var i = 0; i < 1000; i++) {
  KOpush();
}
ready
ModelView 1000
MVclear();
for (var i = 0; i < 1000; i++) {
  MVpush();
}
ready

Revisions

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