Backbone Events vs. Ember Bindings: A Benchmark
Animating 100 (or N) circles with your standard Backbone events and Ember bindings.
by erick
HTML
<script src="http://underscorejs.org/underscore-min.js"></script>
<script src="http://code.angularjs.org/angular-1.0.0rc2.min.js" ng:autobind="angularjsWrapper"></script>
<body ng:app="animationApp" ng:controller="animationCtrl">
<p>
This is an AngularJS <a href="https://news.ycombinator.com/item?id=3616820">animation benchmark</a>, following on from
<a href="http://jsfiddle.net/jashkenas/CGSd5/">the original Backbone/Ember comparison by Jeremy Ashkenas</a>,
<a href="http://jsfiddle.net/HusVw/1/">the original extended with Knockout</a>,
<a href="http://jsfiddle.net/ericf/NrpcQ/">the original extended with YUI</a>,
and <a href="http://jsfiddle.net/krisselden/bYPPT/">a variation on the original</a>.
Here is the original description [with bracketed additions]:
<blockquote>
Folks often ask about how the difference between Backbone and Ember's [and Knockout's and AngularJS's] approaches to model/view binding play out in web apps.
This script uses the latest Backbone.js and Ember.js [Angular.js] to animate 100 circles (or more -- change "N" in the JavaScript),
so that you can see the responsiveness after you click the button, and visualize the speed difference.
The Ember team is aware that in very performance-sensitive situations, like this example, its binding implementation may be too much overhead.
They have reviewed this example, and hope to be able to remove this difference in the future.
Note that this is just a simple benchmark: you wouldn't be doing this in an actual app.
[NB: I've chosen to make this for AngularJS only to avoid creating dynamic HTML,
which is not typical usage of AngularJS.]
</blockquote>
</p>
<div id="angularjsWrapper">
<button ng:click="runAngularjs()">Animate with AngularJS</button>
<div id="grid">
<div class="box-view" ng:repeat="box in boxes">
<div class="box" ng:style="{top: box.top+'px', left: box.left+'px', background:...
CSS
p {
font: 12px/16px Arial;
margin: 10px 10px 15px;
}
button {
font: bold 14px/14px Arial;
margin-left: 10px;
}
#grid {
margin: 10px;
}
.box-view {
width: 20px; height: 20px;
float: left;
position: relative;
margin: 8px;
}
.box {
border-radius: 100px;
width: 20px; height: 10px;
padding: 5px 0;
color: #fff;
font: 10px/10px Arial;
text-align: center;
position: absolute;
}
JavaScript
// Change N to change the number of drawn circles.
var N = 100;
// The AngularJS implementation:
var animationApp = angular.module('animationApp', []);
function animationCtrl($scope, $window, $rootScope) {
var self = this;
$scope.count = 0;
$scope.boxes = new Array();
$scope.Box = function(n) {
this.number = n;
this.top = 0;
this.left = 0;
this.color = 0;
this.content = 0;
this.count = 0;
this.tick = function() {
var count = this.count += 1;
this.top = Math.sin(count / 10) * 10;
this.left = Math.cos(count / 10) * 10;
this.color = count % 255;
this.content = count % 100;
}
}
$scope.angularjsInit = function() {
for (var i = 0; i < N; i++) {
$scope.boxes[i] = new $scope.Box(i);
}
}
$scope.angularjsAnimate = function() {
for (var i = 0; i < N; i++) {
$scope.boxes[i].tick();
}
$rootScope.$apply();
$window.timeout = _.defer($scope.angularjsAnimate);
}
$scope.runAngularjs = function() {
$scope.angularjsInit();
$scope.angularjsAnimate();
}
}