Backbonejs Rendering Collection With Document Fragment

JavaScript performance comparison

Revision 4 of this test case created by Antti Ahti and last updated

Preparation code

<div id="target" style="display:none;"></div>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js">
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.3.3/underscore-min.js">
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/0.9.2/backbone-min.js">
</script>
      
<script>
Benchmark.prototype.setup = function() {
  var Item = Backbone.Model.extend({});
  
  var Items = Backbone.Collection.extend({
    model: Item
  });
  
  var ItemView = Backbone.View.extend({
    template: _.template("<div><%= foo %> : <%= bar %> : <%= baz %></div>"),
    render: function() {
      this.$el.html(this.template(this.model.toJSON()));
      return this;
    }
  });
  
  var ItemViewVar = ItemView.extend({
    template: _.template("<div><%= data.foo %> : <%= data.bar %> : <%= data.baz %></div>", null, {variable: 'data'})
  });
  
  var ItemsViewOne = Backbone.View.extend({
    render: function() {
      var fragment = document.createDocumentFragment();
      _.each(this.collection.models, function(item) {
        var x = new ItemView({
          model: item
        });
        fragment.appendChild(x.render().el);
      }, this);
  
      this.$el.html(fragment);
      return this;
    }
  });
  
  var ItemsViewTwo = Backbone.View.extend({
    render: function() {
      _.each(this.collection.models, function(item) {
        var x = new ItemView({
          model: item
        });
        this.$el.append(x.render().el);
      }, this);
      return this;
    }
  });
  var ItemsViewThree = Backbone.View.extend({
  el: "#target",  
  render: function() {
  this.$el.html("");    
  _.each(this.collection.models, function(item) {
        var x = new ItemView({
          model: item
        });
        this.$el.append(x.render().el);
      }, this);
      return this;
    }
  });
  
  var ItemsViewFour = Backbone.View.extend({
    render: function() {
      var fragment = document.createDocumentFragment();
      _.each(this.collection.models, function(item) {
        var x = new ItemViewVar({
          model: item
        });
        fragment.appendChild(x.render().el);
      }, this);
  
      this.$el.html(fragment);
      return this;
    }
  });
  
  // reasonable number of models
  var items = new Items();
  for (var i = 0; i < 20; i++) {
    items.add({foo: "123", bar: "456", baz: "789"});
  }

};
</script>

Preparation code output

<div id="target" style="display:none;"></div> <script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.3.3/underscore-min.js"> </script> <script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/0.9.2/backbone-min.js"> </script>

Test runner

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

Java applet disabled.

Testing in CCBot 2.0.0 / Other 0.0.0
Test Ops/sec
Using Document Fragment
var view = new ItemsViewOne({
  collection: items
});
$("#target").html(view.render().el);
pending…
Appending Directly
var view = new ItemsViewTwo({
  collection: items
});
$("#target").html(view.render().el);
pending…
Appending to existing dom element
var view = new ItemsViewThree({
  collection: items
});
view.render();
pending…
Using Document Fragment and _.template variable setting
var view = new ItemsViewFour({
  collection: items
});
$("#target").html(view.render().el);
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.

0 Comments