Angular VS Knockout VS ExtJS VS Backbone (v40)

Revision 40 of this benchmark created by Shakti on


Description

The original version purported to insert xxx number of items into a list and demonstrate the performance differences in various platforms. In reality only Ext was actually modifying the DOM since the other frameworks relied on the fact that the inserted item was identical to the previous item. In the case of Ext the store is cleared in code and then reapplied whereas the others simply reapply the same data. This revision modifies the Angular and Knockout code to first clear the list before re-inserting it so all frameworks are on equal footings and actually do inserts. It also updates Ext to the latest version and uses a View instead of a Grid so that the platforms are creating similar markup with similar capabilities.

TODO: the Knockout code was not(and still isn't) creating anything close to the Angular or EXT output. I have attempted to fix this but as of now it still doesn't render.

Preparation HTML

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

<!-- ANGULAR -->
<script src="http://code.angularjs.org/angular-1.0.1.min.js" ng:autobind></script>
<script>
 
var Ctrl=function($scope){
        $scope.data=[];
}
</script>
<div ng:app>
Angular:<BR>
<ul ng-controller="Ctrl" id="angList"  >
<li ng-repeat="item in data">{{item}}</li>
</ul>

<script>
var SetANG= function(data){
$('#angList').scope().data=[];
$('#angList').scope().$apply(function(){});
$('#angList').scope().data=data;
$('#angList').scope().$apply(function(){});
};
</script>        


<!-- ANGULAR Update -->
 <script>
 
var CtrlUpdate=function($scope){
        $scope.data=[];
}
</script>
ANGULAR Update:<BR>
<ul ng-controller="CtrlUpdate" id="angListUpdate"  >
<li ng-repeat="item in data">{{item}}</li>
</ul></div>
</div>
<script>
var SetANGUpdate= function(data){
$('#angListUpdate').scope().data=data;
$('#angListUpdate').scope().$apply(function(){});
};
</script>        


<!-- EXT -->
<script  src="http://docs.sencha.com/extjs/4.0.0/extjs/ext-all.js"></script>
<div>
EXT:<BR>
<ul id='extOutput'>
</div>
<script>
 
var store = Ext.create('Ext.data.Store', {
    storeId:'employeeStore',
    fields:['name' ],
    data: []     
});
var viewTpl = new Ext.XTemplate(
    '<tpl for=".">',
       '<li>{name}</li>',
    '</tpl>'
);

Ext.create('Ext.view.View', {
    store: Ext.data.StoreManager.lookup('employeeStore'),
    tpl: viewTpl,
    itemSelector: '',
    emptyText: 'No text',
    renderTo: 'extOutput'
}); 

 
var SetEXT=function (data){    
    store.removeAll();
    store.loadRawData(data);    
};</script>


<!-- KO -->
<script src="http://cdnjs.cloudflare.com/ajax/libs/knockout/2.0.0/knockout-min.js"></script>
<script>var KOData=null;</script>
KO:<BR>
<div>
<ul id="KOTest" data-bind="foreach: KOData">
  <li><span data-bind="text: name"></span> </li>
</ul>
</div>  
<script>
KOData=ko.observable([]);
ko.applyBindings(); 
var SetKO=function (data){
KOData=ko.observable([]);
ko.applyBindings();

KOData=ko.observable(data);
ko.applyBindings();
} 
</script>





<script>
var ANG5ID=[];
for (var i=0; i<5;i++){
ANG5ID.push('ITEM'+i);
};
var EXT5ID=[];
for (var i=0; i<5;i++){
EXT5ID.push({name:'ITEM'+i});
};
var KO5ID=[];
for (var i=0; i<5;i++){
KO5ID.push({name: 'ITEM'+i});
};


var ANG50ID=[];
for (var i=0; i<50;i++){
ANG50ID.push('ITEM');
};
var EXT50ID=[];
for (var i=0; i<50;i++){
EXT50ID.push({name:'ITEM'});
};
var KO50ID=[];
for (var i=0; i<50;i++){
KO50ID.push({name: 'ITEM'});
};


var ANG100ID=[];
for (var i=0; i<100;i++){
ANG100ID.push('ITEM');
};
var EXT100ID=[];
for (var i=0; i<100;i++){
EXT100ID.push({name:'ITEM'});
};
var KO100ID=[];
for (var i=0; i<100;i++){
KO100ID.push({name: 'ITEM'});
};



var ANG1000ID=[];
for (var i=0; i<1000;i++){
ANG1000ID.push('ITEM');
};
var EXT1000ID=[];
for (var i=0; i<1000;i++){
EXT1000ID.push({name:'ITEM'});
};
var KO1000ID=[];
for (var i=0; i<1000;i++){
KO1000ID.push({name: 'ITEM'});
};
</script>

Setup

SetANG(ANG5ID);
    SetEXT(EXT5ID);
    SetKO(KO5ID);
    
    SetANGUpdate(ANG100ID);

Test runner

Ready to run.

Testing in
TestOps/sec
Angular 0-50 Items
SetANG(ANG50ID);
 
ready
Knockout 0-50 Items
SetKO(KO50ID);
ready
ExtJS 0-50 Items
SetEXT(EXT50ID);
ready
Backbone 0-50 Items/TODO
 
ready
Angular 0-100 Items
SetANG(ANG100ID);
ready
Knockout 0-100 Items
SetKO(KO100ID);
ready
ExtJS 0-100 Items
SetEXT(EXT100ID);
ready
Backbone 0-100 Items/TODO
 
ready
Angular 0-1000 Items
SetANG(ANG1000ID);
ready
Knockout 0-1000 Items
SetKO(KO1000ID);
ready
ExtJS 0-1000 Items
SetEXT(EXT1000ID);
ready
Backbone 0-1000 Items/TODO
 
ready
Angular Update 10 of 100
ANG100ID[3]="changed1"
ANG100ID[7]="changed2"
ANG100ID[76]="changed3"
ANG100ID[31]="changed4"
ANG100ID[5]="changed5"

SetANGUpdate(ANG100ID);
ready

Revisions

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