Backbone.js : subviews rendering (v3)

Revision 3 of this benchmark created by Bruno Mendes on


Preparation HTML

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script src="https://documentcloud.github.com/underscore/underscore-min.js"></script>
<script src="https://documentcloud.github.com/backbone/backbone-min.js"></script>

<div id='rendered'>
</div>



<script id="tpl1-table" type="text/template">
    <table>
        <caption><%= caption %></caption>
        <thead>
            <tr>
                <th>Row</th>                
                <th>Name</th>
            </tr>
        </thead>
        <tbody></tbody>
     </table>
</script>
<script id="tpl1-row" type="text/template">
    <td><%= row %></td>                
    <td><%= name %></td>
</script>

<script id="tpl2-table" type="text/template">
    <table>
        <caption><%= caption %></caption>
        <thead>
            <tr>
                <th>Row</th>                
                <th>Name</th>
            </tr>
        </thead>
        <tbody>
        <% _(children).each(function(model) { %>
            <tr id='<%= model.cid %>'>
                <td><%= model.row %></td>
                <td><%= model.name %></td>
            </tr>
        <% }); %>
        </tbody>
     </table>
</script>

<script id="tpl3-table" type="text/template">
    <table>
        <caption><%= caption %></caption>
        <thead>
            <tr>
                <th>Row</th>                
                <th>Name</th>
            </tr>
        </thead>
        <tbody>
        <% _(children).each(function(model) {
            print( subtemplate(model) );
        }); %>
        </tbody>
     </table>
</script>

<script id="tpl3-row" type="text/template">
    <tr id='<%= cid %>'>
        <td><%= row %></td>                
        <td><%= name %></td>
    </tr>
</script>

<script id="tpl4-table" type="text/template">

    <table>
        <caption><%= collection.caption %></caption>
        <thead>
            <tr>
                <th>Row</th>                
                <th>Name</th>
            </tr>
        </thead>
        <tbody>
        <% _(collection.children).each(function(model) {
            print( collection.subtemplate(model) );
        }); %>
        </tbody>
     </table>
</script>

<script id="tpl4-row" type="text/template">
    <tr id='<%= model.cid %>'>
        <td><%= model.row %></td>                
        <td><%= model.name %></td>
    </tr>
</script>

<script id="tpl5-table" type="text/template">
    <table>
        <caption><%= caption %></caption>
        <thead>
            <tr>
                <th>Row</th>                
                <th>Name</th>
            </tr>
        </thead>
        <tbody>
        <% _(children).each(function(model, i) { %>
            <tr>
                <td><%= model.row %></td>
                <td><%= model.name %></td>
            </tr>
        <% }); %>
        </tbody>
     </table>
</script>

<script id="tpl6-table" type="text/template">
    <table>
        <caption><%= caption %></caption>
        <thead>
            <tr>
                <th>Row</th>                
                <th>Name</th>
            </tr>
        </thead>
        <tbody>
                <%= _(children).map(function(model) {
                        return subtemplate(model)
                }).join('') %>
        </tbody>
     </table>
</script>
<script id="tpl6-row" type="text/template">
        <tr>
                <td><%= row %></td>
                <td><%= name %></td>
        </tr>
</script>

<script id="tpl7-table" type="text/template">
    <table>
        <caption><%= caption %></caption>
        <thead>
            <tr>
                <th>Row</th>                
                <th>Name</th>
            </tr>
        </thead>
                <tbody>
                </tbody>
     </table>
</script>
<script id="tpl7-row" type="text/template">
    <td><%= row %></td>                
    <td><%= name %></td>
</script>

Setup

var data = [];
    for (var i = 0, row = 0; i < 100; i++) {
        row = _.random(row+1, row+1+i)
      data.push({
        row: row,
        name: "Row " + row
      });
    }
    
    var coll = new Backbone.Collection(data);
    
    var ItemView = Backbone.View.extend({
      events: {
        "click td": "show"
      },
      show: function() {
        console.log(this.model.get("name"));
      }
    });
    
    
    var Test1ItemView = ItemView.extend({
      template: _.template($('#tpl1-row').html()),
    
      render: function() {
        this.$el.html(this.template(this.model.toJSON()))
        
        return this;
      }
    });
    
    var Test1ListView = Backbone.View.extend({
      template: _.template($('#tpl1-table').html()),
    
      render: function() {
        var html = this.template({
          caption: "Test 1"
        });
    
        this.$el.empty();
        this.$el.append(html);
        var $tbody = this.$el.find('table tbody');
    
        this.collection.each(function(model) {
          var view = new Test1ItemView({
            model: model,
                tagName: 'tr'
          });
          var $tr = view.render().$el;
          $tbody.append($tr);
        });
    
        return this;
      }
    });
    
    
    var Test2ListView = Backbone.View.extend({
      template: _.template($('#tpl2-table').html()),
    
      render: function() {
        var data = this.collection.map(function(model) {
          return _.extend(model.toJSON(), {
            cid: model.cid
          });
        });
        var html = this.template({
          children: data,
          caption: "Test 2"
        });
        
        this.$el.empty();
        this.$el.append(html);
    
        var $table = this.$el.find('table');
    
        this.collection.each(function(model) {
          new ItemView({
            el: $table.find("#" + model.cid),
            model: model
          });
        })
    
        return this;
      }
    });
    
    var Test3ListView = Backbone.View.extend({
      template: _.template($('#tpl3-table').html()),
      subtemplate: _.template($('#tpl3-row').html()),
    
      render: function() {
    
        var data = this.collection.map(function(model) {
          return _.extend(model.toJSON(), {
            cid: model.cid
          });
        });
        var html = this.template({
          children: data,
          subtemplate: this.subtemplate,
          caption: "Test 3"
        });
        
        this.$el.empty();
        this.$el.append(html);
    
        var $table = this.$el.find('table');
    
        this.collection.each(function(model) {
          new ItemView({
            el: $table.find("#" + model.cid),
            model: model
          });
        });
    
        return this;
      }
    });
    
    var Test4ListView = Backbone.View.extend({
      template: _.template($('#tpl4-table').html(), null, {
        variable: 'collection'
      }),
      subtemplate: _.template($('#tpl4-row').html(), null, {
        variable: 'model'
      }),
    
      render: function() {
    
        var data = this.collection.map(function(model) {
          return _.extend(model.toJSON(), {
            cid: model.cid
          });
        });
        var html = this.template({
          children: data,
          subtemplate: this.subtemplate,
          caption: "Test 4"
        });
        
        this.$el.empty();
        this.$el.append(html);
    
        var $table = this.$el.find('table');
    
        this.collection.each(function(model) {
          new ItemView({
            el: $table.find("#" + model.cid),
            model: model
          });
        });
    
        return this;
      }
    });
    
    var Test5ListView = Backbone.View.extend({
      template: _.template($('#tpl5-table').html()),
      render: function() {
        var html = this.template({
          children: this.collection.toJSON(),
          caption: 'Test 5'
        })
        
          this.$el.append(html)
    
        var trArray = this.$el.find('table tbody').children('tr')
    
        this.collection.each(function(model, i) {
          new ItemView({
            el: trArray[i],
            model: model
          })
        })
    
        return this
      }
    })
    
    var Test6ListView = Backbone.View.extend({
      template: _.template($('#tpl6-table').html()),
      subtemplate: _.template($('#tpl6-row').html()),
      render: function() {
        var html = this.template({
          children: this.collection.toJSON(),
          caption: 'Test 6',
          subtemplate: this.subtemplate
        })
        
        this.$el.empty()
        this.$el.append(html)
    
        var trArray = this.$el.find('table tbody').children('tr')
    
        this.collection.each(function(model, i) {
          new ItemView({
            el: trArray[i],
            model: model
          })
        })
    
        return this
      }
    })
    
    var Test7ItemView = ItemView.extend({
      template: _.template($('#tpl7-row').html()),
    
      render: function() {
        this.$el.html(this.template(this.model.toJSON()))
        
        return this
      }
    })
    var Test7ListView = Backbone.View.extend({
      template: _.template($('#tpl7-table').html()),
    
      render: function() {
        this.$el.empty()
    
        var html = this.template({
          caption: "Test 7"
        })
        this.$el.append(html)
        
        var itemsHtml = ''
        this.collection.each(function(model) {
          var view = new Test1ItemView({
            model: model,
                tagName: 'tr'
          });
          itemsHtml += view.render().$el[0].outerHTML
        })
        this.$el.find('table tbody').append(itemsHtml)
    
        return this
      }
    })
    
    var view1 = new Test1ListView({
      collection: coll
    });
    $("#rendered").append(view1.el);
    
    var view2 = new Test2ListView({
      collection: coll
    });
    $("#rendered").append(view2.el);
    
    var view3 = new Test3ListView({
      collection: coll
    });
    $("#rendered").append(view3.el);
    
    var view4 = new Test4ListView({
      collection: coll
    });
    $("#rendered").append(view4.el);
    
    var view5 = new Test5ListView({
      collection: coll
    })
    $("#rendered").append(view5.el)
    
    var view6 = new Test6ListView({
      collection: coll
    })
    $("#rendered").append(view6.el)
    
    var view7 = new Test7ListView({
      collection: coll
    })
    $("#rendered").append(view7.el)

Teardown


    $("#rendered").empty();
  

Test runner

Ready to run.

Testing in
TestOps/sec
Render subview and append
view1.render();
ready
Unique template
view2.render();
ready
Compiled subtemplate, variable not set
view3.render();
ready
Compiled subtemplate, variable set
view4.render();
ready
Unique template, no item id
view5.render()
ready
Compiled subtemplate, variable not set, no item id
view6.render()
ready
Render subview, cache html and then append
view7.render()
ready

Revisions

You can edit these tests or add more tests to this page by appending /edit to the URL.