Knockout.js vs Backbone.js vs Direct DOM Manipulation

JavaScript performance comparison

Revision 6 of this test case created

Preparation code

<div id="test">
  <ul id="knockout" data-bind="foreach: jokes">
    <li data-bind="text: joke" />
  </ul>
  <ul id="dom">
  </ul>
  <ul id="backbone">
  </ul>
</div>
<script type="text/template" id="backbone-template">
  < li > < %= joke % > < /li>
</script>
<script src="//cloud.github.com/downloads/SteveSanderson/knockout/knockout-2.2.0.js">
</script>
<script src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.3.1/underscore-min.js">
</script>
<script src="//cdnjs.cloudflare.com/ajax/libs/backbone.js/0.9.1/backbone-min.js">
</script>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js">
</script>
<script>
Benchmark.prototype.setup = function() {
    // Reset DOM
    var el = document.getElementById('test');
    el.outerHTML = '<div id="test"><ul id="knockout" data-bind="foreach: jokes"><li data-bind="text: joke"/></ul><ul id="dom"></ul><ul id="backbone"></ul></div>';
   
    var jokes = [{
      joke: "How many programmers does it take to change a light bulb? None – It’s a hardware problem"
    }, {
      joke: "Programming is like sex: One mistake and you have to support it for the rest of your life."
    }, {
      joke: "There are three kinds of lies: Dark Lies, white lies, and benchmarks."
    }];
   
    /* Knockout.js */
   
    function ViewModel() {
      this.jokes = jokes;
    }
   
    /* Backbone.js */
    Backbone.setDomLibrary(jQuery);
   
    var Model = Backbone.Model.extend({
      defaults: function() {
        return {
          joke: null
        };
      }
    });
   
    var Collection = Backbone.Collection.extend({
      model: Model
    });
   
    var collection = new Collection();
   
    var View = Backbone.View.extend({
      tagName: 'li',
      template: _.template($('#backbone-template').html()),
   
      render: function() {
        $(this.el).html(this.template(this.model.toJSON()));
        return this;
      }
    });
   
    var AppView = Backbone.View.extend({
      el: $('#backbone'),
      initialize: function() {
        collection.bind('add', this.addOne, this);
        collection.bind('reset', this.addAll, this);
   
        collection.reset(jokes);
      },
      addOne: function(joke) {
        var view = new View({
          model: joke
        });
        $('#backbone').append(view.render().el);
      },
   
      addAll: function() {
        collection.each(this.addOne);
      },
    });
};
</script>

Preparation code output

Test runner

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

Java applet disabled.

Testing in unknown unknown
Test Ops/sec
Knockout.js
// Reset DOM
var el = document.getElementById('test');
el.outerHTML = '<div id="test"><ul id="knockout" data-bind="foreach: jokes"><li data-bind="text: joke"/></ul><ul id="dom"></ul><ul id="backbone"></ul></div>';
el = document.getElementById('knockout');

// Run Knockout.js
ko.applyBindings(new ViewModel(), document.getElementById('knockout'));
pending…
Direct DOM Manipulation
// Reset DOM
var el = document.getElementById('test');
el.outerHTML = '<div id="test"><ul id="knockout" data-bind="foreach: jokes"><li data-bind="text: joke"/></ul><ul id="dom"></ul><ul id="backbone"></ul></div>';
el = document.getElementById('dom');

// Manipulate DOM
for (var i in jokes) {
  var li = document.createElement('li');
  li.appendChild(document.createTextNode(jokes[i].joke));
  el.appendChild(li);
}
pending…
Backbone.js
// Reset DOM
var el = document.getElementById('test');
el.outerHTML = '<div id="test"><ul id="knockout" data-bind="foreach: jokes"><li data-bind="text: joke"/></ul><ul id="dom"></ul><ul id="backbone"></ul></div>';

// Run Backbone.js
collection = new Collection(); // workaround: collection.reset doesn't seem to clear old items
var v = new AppView();
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:

0 comments

Add a comment