Angular vs. jQuery vs. Native vs. Native (New School)

JavaScript performance comparison

Revision 25 of this test case created

Info

Extended the original test to include Ember.

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 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.1.3/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 = [];
      angScope.$apply();
    };
    window.angularPush = function(data){
      angScope.data.push(data);
    };
    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 () {
  while (nativeEl.hasChildNodes()) {
    nativeEl.removeChild(nativeEl.lastChild);
  }
  nativeChildren = null;
  nativeChildren = '';
}


</script>


<!-- Native New -->
<h1>New Native (querySelector):</h1>
<div id="native_test_new"></div>

<script type="text/javascript">
var newNativeEl = document.querySelector('#native_test_new');
var newNativeChildren = '';
var newNativePush = function (data) {
  var el = '<span>' + data + '</span>';
  newNativeChildren += el;
}
var newNativeRender = function () {
  newNativeEl.innerHTML = newNativeChildren;
}
var newNativeClear = function () {
  while (newNativeEl.hasChildNodes()) {
    newNativeEl.removeChild(newNativeEl.lastChild);
  }
  newNativeChildren = null;
  newNativeChildren = '';
}


</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>

<h1>Native (getElementById):</h1>
<div id="native_opt_test"></div>

<script type="text/javascript">
var nativeOptEl = document.getElementById('native_opt_test');
var nativeOptChildren = document.createDocumentFragment();
var nativeTemplate = document.createElement('span');
var nativeOptPush = function (data) {
  var el = nativeTemplate.cloneNode();
   el.innerHTML = data;
  nativeOptChildren.appendChild(el);
}
var nativeOptRender = function () {
  nativeOptEl.appendChild(nativeOptChildren);
}
var nativeOptClear = function () {
  while (nativeOptEl.hasChildNodes()) {
    nativeOptEl.removeChild(nativeOptEl.lastChild);
  }
  nativeOptChildren = document.createDocumentFragment();
}


</script>

Preparation code output

jQuery:

Angular:

{{item}}

Native (getElementById):

New Native (querySelector):

Ember:

Native (getElementById):

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 500
angularClear();
for (var i = 0; i < 500; i++) {
  angularPush('ng-item');
}
angularApply();


 
pending…
Ember 500
EMclear();
Ember.beginPropertyChanges();
for (var i = 0; i < 500; i++) {
  EMpush("emitem");
}
Ember.endPropertyChanges();
window.run_number_em++;
pending…
Native 500
nativeClear();
for (var i = 0; i < 500; i++) {
  nativePush('native-item');
}
nativeRender();
pending…
New Native 500
newNativeClear();
for (var i = 0; i < 500; i++) {
  newNativePush('native-item-new');
}
newNativeRender();
pending…
jQuery 500
jqClear();
for (var i = 0; i < 500; i++) {
  jqPush('jq-item');
}
jqRender();
 
pending…
Native Optimized
nativeOptClear();
for (var i = 0; i < 500; i++) {
  nativeOptPush('native-item');
}
nativeOptRender();
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

One Guy commented :

Thank you for publishing these results. Can you provide more background information and perhaps some interpretation? The results seem inconsistent. For example, Rev 24 shows jQuery 100 as being faster than Angular 100. Yet in Rev 25 this performance comparison is reversed?

Add a comment