Angular VS Knockout VS Ember
JavaScript performance comparison
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.
| Test | Ops/sec | |
|---|---|---|
Angular 10 |
|
pending… |
Knockout 10 |
|
pending… |
Ember 10 |
|
pending… |
Angular 100 |
|
pending… |
Knockout 100 |
|
pending… |
Ember 100 |
|
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:
- Revision 1: published by Matt Peterson
- Revision 2: published
- Revision 10: published by dain
- Revision 11: published
- Revision 13: published
- Revision 14: published
- Revision 18: published
- Revision 20: published by Bevan Hunt
- Revision 21: published
- Revision 22: published
- Revision 24: published
- Revision 25: published by Jacob
- Revision 30: published
- Revision 32: published by Steve Commisso
- Revision 33: published by Steve Commisso
- Revision 35: published
- Revision 36: published
- Revision 37: published by Lennaert Meijvogel
- Revision 38: published
- Revision 39: published
- Revision 40: published
- Revision 41: published
- Revision 42: published
- Revision 43: published
- Revision 44: published
- Revision 46: published
- Revision 48: published
- Revision 49: published
- Revision 50: published
- Revision 51: published
- Revision 52: published by Jose S.
- Revision 53: published by Jose S.
- Revision 54: published
- Revision 56: published
- Revision 57: published
- Revision 58: published by kmdsbng
- Revision 59: published by kmdsbng
- Revision 60: published by hakurai
- Revision 61: published by Jose S.
- Revision 62: published
- Revision 63: published
- Revision 64: published
- Revision 68: published
- Revision 69: published
- Revision 70: published
- Revision 73: published
- Revision 74: published
- Revision 75: published
- Revision 76: published
- Revision 77: published
- Revision 78: published
- Revision 79: published
- Revision 80: published
- Revision 81: published
- Revision 82: published
- Revision 83: published
- Revision 84: published by bieber
- Revision 85: published
- Revision 87: published
- Revision 88: published by cihan
- Revision 89: published
- Revision 90: published
- Revision 91: published
- Revision 92: published
- Revision 93: published
- Revision 94: published by SurelyPlus and last updated
- Revision 95: published
- Revision 96: published
- Revision 97: published
- Revision 98: published by Matt Webb
- Revision 99: published by balazsbela
- Revision 100: published by thelinuxlich
- Revision 103: published
- Revision 104: published by Roman
- Revision 105: published
- Revision 106: published
- Revision 107: published
- Revision 108: published by m_gol
- Revision 109: published
- Revision 110: published
- Revision 111: published
- Revision 114: published
- Revision 115: published
- Revision 116: published by Sebastian
- Revision 117: published by Sebastian
- Revision 118: published
- Revision 119: published
- Revision 120: published
- Revision 122: published
- Revision 123: published by Joe Wagner
- Revision 124: published by Dave
- Revision 125: published
- Revision 126: published
- Revision 129: published
- Revision 132: published
- Revision 133: published
- Revision 134: published
- Revision 135: published
- Revision 136: published
- Revision 137: published
- Revision 138: published
- Revision 140: published
- Revision 141: published
- Revision 142: published
- Revision 143: published
1 comment
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.