Angular VS Knockout VS ExtJS VS Backbone

JavaScript performance comparison

Revision 40 of this test case created by Shakti

Info

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 code

<!-- 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>
<script>
Benchmark.prototype.setup = function() {
    SetANG(ANG5ID);
    SetEXT(EXT5ID);
    SetKO(KO5ID);
   
    SetANGUpdate(ANG100ID);
};
</script>

Preparation code output

Angular:
  • {{item}}
ANGULAR Update:
  • {{item}}
EXT:
KO:

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 0-50 Items
SetANG(ANG50ID);
 
pending…
Knockout 0-50 Items
SetKO(KO50ID);
pending…
ExtJS 0-50 Items
SetEXT(EXT50ID);
pending…
Backbone 0-50 Items/TODO
 
pending…
Angular 0-100 Items
SetANG(ANG100ID);
pending…
Knockout 0-100 Items
SetKO(KO100ID);
pending…
ExtJS 0-100 Items
SetEXT(EXT100ID);
pending…
Backbone 0-100 Items/TODO
 
pending…
Angular 0-1000 Items
SetANG(ANG1000ID);
pending…
Knockout 0-1000 Items
SetKO(KO1000ID);
pending…
ExtJS 0-1000 Items
SetEXT(EXT1000ID);
pending…
Backbone 0-1000 Items/TODO
 
pending…
Angular Update 10 of 100
ANG100ID[3]="changed1"
ANG100ID[7]="changed2"
ANG100ID[76]="changed3"
ANG100ID[31]="changed4"
ANG100ID[5]="changed5"

SetANGUpdate(ANG100ID);
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:

0 comments

Add a comment