Mask / Angular / jQuery / Ember

JavaScript performance comparison

Revision 31 of this test case created

Info

Preparation code

<!-- Jquery -->
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<h1>jQuery:</h1>
<div id="jq_test"></div>

<script type="text/javascript">
var MAX = 50, index = 0, counter = 0;
var jqEl = $('#jq_test');
var children = '';
var jqPush = function (data) {
  children += '<span>' + data + '</span>';
}
var jqRender = function () {
  jqEl.append(children);
  //jqEl.append('<span>' + data + '</span>');
}
var jqClear = function () {
  jqEl.empty();
  children = '';
}
</script>

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

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

<script type="text/javascript">
  var Ctrl = function($scope){
    $scope.data = [];
  }
 
  angular.element(document).ready(function() {
    var angScope = $('#angList').scope();
   
    window.angularClear = function(){
      angScope.data.splice(0, angScope.data.length);
     // angScope.$digest();
    };
    window.angularPush = function(data){
      angScope.data.push(data);
     // angScope.$digest();
    };
    window.angularApply = function(data){
      angScope.$apply();
    };
  });
</script>

<!-- Native -->
<h1>Native (getElementById):</h1>
<div id="native_test"></div>

<script type="text/javascript">
var nativeEl = document.getElementById('native_test');
var nativeChildren = '';
var nativePush = function (data) {
  var el = '<span>' + data + '</span>';
  nativeChildren += el;
}
var nativeRender = function () {
  nativeEl.innerHTML = nativeChildren;
}
var nativeClear = function () {
  nativeEl.innerHTML = "";
  nativeChildren = null;
  nativeChildren = '';
}


</script>




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

<script>
  var ENV = {EXTEND_PROTOTYPES: false};
</script>

<script>
  var ENV = {
    EXTEND_PROTOTYPES: false
  };
</script>
<script src="https://github.com/downloads/wycats/handlebars.js/handlebars-1.0.rc.1.js">
</script>
<script src="https://github.com/downloads/emberjs/ember.js/ember-1.0.0-pre.2.min.js">
</script>
<script>
  EMapp = Ember.Application.create({
    rootElement: $('#emapp')
  });
  EMapp.data = Ember.A();

  EMclear = function() {
    EMapp.set("data", Ember.A());
  };

  EMpush = function(data) {
    EMapp.data.pushObject(data);
  };
</script>

<script src="https://rawgithub.com/atmajs/MaskJS/master/lib/mask.min.js?v=.9"></script>
<h1>Mask:</h1>
<div id="mask_test"></div>
<script>
 
  window.mask_Model = { arr: [] };
 
  // binded arr property
  var template = "div > %% each=arr > span > '~[.]'",
      dom = mask.render(template, mask_Model),
      element = document.querySelector('#mask_test');

  element.appendChild(dom);
 

 

</script>
<script>
Benchmark.prototype.teardown = function() {
    counter = 0;
};
</script>

Preparation code output

jQuery:

Angular:

{{item}}

Native (getElementById):

Ember:

Mask:

Test runner

Warning! For accurate results, please disable Firebug before running the tests. (Why?)

Java applet disabled.

Testing in unknown unknown
Test Ops/sec
Mask
var newArr = [];
index = MAX;
while(--index) newArr.push('msk-item' + (counter++));

mask_Model.arr = newArr ;
pending…
Ember
EMclear();
Ember.beginPropertyChanges();
index = MAX;
while(--index)   EMpush("em-item" + (counter++));

Ember.endPropertyChanges();
window.run_number_em++;
pending…
Angular
angularClear();
index = MAX;
while(--index) angularPush('ng-item' + (counter++));
angularApply();
pending…
jQuery
jqClear();
index = MAX;
while(--index)   jqPush('jq-item' + (counter++));

jqRender();
 
pending…
Native
nativeClear();
index = MAX;
while(--index) nativePush('native-item');

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

1 comment

Kfir commented :

I think that this test does not realy compare the same performance. Looking at jquery code, the test build a string in 100 iterations and then insert it in one operation to the dom. Looking at angular the script update the dom element by element (and even then it uses jqlite for some reason to render which is unecesary. I would suggest to change as follow: 1. Change the jquery code to render inside each iteration. 2. Remove all DOM manipulations from angular. Just update the scope in the controller and let ng-repeat directive do its magic.

Add a comment