AngularJs vs Backbone

JavaScript performance comparison

Test case created by Max

Preparation code

<!-- AngularJs -->
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.1.5/angular.min.js"></script>

<script>
var angularScope;

function changeAngularModel() {
  angularScope.model.width = 128;
  angularScope.model.height = 192;
  angularScope.model.powerOfTwo = true;
  angularScope.model.maintainAspectRatio = true;
  angularScope.model.background = '#00ffff';
  angularScope.$apply();
}

function Controller($scope) {
    $scope.model = {
        width: 8192,
        height: 8192,
        powerOfTwo: false,
        maintainAspectRatio: false,
        background: '#ff00ff'
    };
   
    angularScope = $scope;
}
</script>

<fieldset ng-controller="Controller" ng-app>
  <legend>Properties</legend>

  <label>Width</label>
  <input type="text" size="4" maxlength="4" ng-model="model.width" ng-hide="model.powerOfTwo" required>
  <select ng-show="model.powerOfTwo">
    <option>1</option>
    <option>2</option>
    <option>4</option>
    <option>8</option>
    <option>16</option>
    <option>32</option>
    <option>64</option>
    <option>128</option>
    <option>256</option>
    <option>512</option>
    <option>1024</option>
    <option>2048</option>
    <option>4096</option>
    <option>8192</option>
  </select>

  <label>Height</label>
  <input type="text" size="4" maxlength="4" ng-model="model.height" ng-hide="model.powerOfTwo" required>
  <select ng-show="model.powerOfTwo">
    <option>1</option>
    <option>2</option>
    <option>4</option>
    <option>8</option>
    <option>16</option>
    <option>32</option>
    <option>64</option>
    <option>128</option>
    <option>256</option>
    <option>512</option>
    <option>1024</option>
    <option>2048</option>
    <option>4096</option>
    <option>8192</option>
  </select>

  <label>Power of two</label>
  <input type="checkbox" ng-model="model.powerOfTwo">

  <label class="checkbox">Maintain aspect ratio</label>
  <input type="checkbox" ng-model="model.maintainAspectRatio">

  <label>Background</label>
  <input type="color" ng-model="model.background">
</fieldset>

<!-- Backbone -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.4.4/underscore-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.0.0/backbone-min.js"></script>

<script>
var backboneModel;

function changeBackboneModel() {
 backboneModel.set({
  width: 23,
  height: 45,
  powerOfTwo: true,
  maintainAspectRatio: true,
  background: '#00ff00'
 });
}

$(function() {
  var Model = Backbone.Model.extend({
    defaults: function() {
      return {
        width: 8192,
        height: 8192,
        powerOfTwo: false,
        maintainAspectRatio: false,
        background: '#ffff00'
      };
    },
    togglePowerOfTwo: function() {
      this.set({powerOfTwo: !this.get("powerOfTwo")});
    },
    toggleMaintainAspectRatio: function() {
      this.set({maintainAspectRatio: !this.get("maintainAspectRatio")});
    }
  });

  var View = Backbone.View.extend({
    // View element
    el: $('#properties'),

    // Cached controls
    widthInput: $('#width-input'),
    heightInput: $('#height-input'),
    backgroundInput: $('#background-input'),

    // Templates
    template: _.template($('#properties-template').html()),

    /**
     * Register action handlers.
     */

    events: {
      'change #width-input': 'setWidth',
      'change #height-input': 'setHeight',
      'change #background-input': 'setBackground',
      'change #power-of-two-input': 'togglePowerOfTwo',
      'change #maintain-aspect-ratio-input': 'toggleMaintainAspectRatio'
    },

    /**
     * Initializes the sheet view.
     */

    initialize: function() {
      this.listenTo(this.model, 'change', this.render);
      this.listenTo(this.model, 'destroy', this.remove);
    },

    /**
     * Render
     */

    render: function() {
      this.$el.html(this.template(this.model.toJSON()));

      //widthInput = $('#width-input');
      //heightInput = $('#height-input');
    },

    setWidth: function() {
      this.model.set({width: this.widthInput.val()});
    },

    setHeight: function() {
      this.model.set({height: this.heightInput.val()});
    },

    setBackground: function() {
      this.model.set({background: this.backgroundInput.val()});
    },

    /**
     * Toggles the power of two option.
     */

    togglePowerOfTwo: function(e) {
      this.model.togglePowerOfTwo();
    },

    /**
     * Toggles the maintain aspect ratio option.
     */

    toggleMaintainAspectRatio: function() {
      this.model.toggleMaintainAspectRatio();
    }
  });

  backboneModel = new Model;

  var view = new View({model: backboneModel});
});
</script>

<fieldset id="properties">
  <legend>Properties</legend>

  <label for="width-input">Width</label>
  <input id="width-input" type="text" size="4" maxlength="4" value="8192" required>

  <label for="height-input">Height</label>
  <input id="height-input" type="text" size="4" maxlength="4" value="8192" required>

  <label for="power-of-two-input">Power of two</label>
  <input id="power-of-two-input" type="checkbox">

  <label for="maintain-aspect-ratio-input" class="checkbox">Maintain aspect ratio</label>
  <input id="maintain-aspect-ratio-input" type="checkbox">

  <label for="background-input">Background</label>
  <input id="background-input" type="color">
</fieldset>

<script id="properties-template" type="text/template">
  <legend>Properties</legend>

  <label for="width-input">Width</label>
  <input id="width-input" type="text" size="4" maxlength="4" value="<%= width %>" style="display: <%= powerOfTwo ? 'none' : 'inline' %>" required>
  <select id="width-combo" style="display: <%= powerOfTwo ? 'inline' : 'none' %>">
    <option>1</option>
    <option>2</option>
    <option>4</option>
    <option>8</option>
    <option>16</option>
    <option>32</option>
    <option>64</option>
    <option>128</option>
    <option>256</option>
    <option>512</option>
    <option>1024</option>
    <option>2048</option>
    <option>4096</option>
    <option>8192</option>
  </select>

  <label for="height-input">Height</label>
  <input id="height-input" type="text" size="4" maxlength="4" value="<%= height %>" style="display: <%= powerOfTwo ? 'none' : 'inline' %>" required>
  <select id="height-combo" style="display: <%= powerOfTwo ? 'inline' : 'none' %>">
    <option>1</option>
    <option>2</option>
    <option>4</option>
    <option>8</option>
    <option>16</option>
    <option>32</option>
    <option>64</option>
    <option>128</option>
    <option>256</option>
    <option>512</option>
    <option>1024</option>
    <option>2048</option>
    <option>4096</option>
    <option>8192</option>
  </select>

  <label for="power-of-two-input">Power of two</label>
  <input id="power-of-two-input" type="checkbox" <%= powerOfTwo ? 'checked' : '' %>>

  <label for="maintain-aspect-ratio-input" class="checkbox">Maintain aspect ratio</label>
  <input id="maintain-aspect-ratio-input" type="checkbox" <%= maintainAspectRatio ? 'checked' : '' %>>

  <label for="background-input">Background</label>
  <input id="background-input" type="color" value="<%= background %>">
</script>

Preparation code output

Properties
Properties

Test runner

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

Java applet disabled.

Testing in unknown unknown
Test Ops/sec
AngularJs
changeAngularModel();
pending…
Backbone
changeBackboneModel();
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

Kate Heddleston commented :

This is awesome! I've been meaning to do some performance testing comparisons between the two.

Add a comment