Backbone Marionette慢速复合视图(200多个系列)

时间:2014-12-09 05:07:52

标签: backbone.js collections marionette

当显示大约200个国家/地区的下拉式复合视图集时,我的应用程序变得太慢了。

在木偶复合视图中处理大型集合时,提高性能的最佳方法是什么?

这是控制器中加载速度很慢的功能。它很快,只删除了以下几行:

 @layout.shippingCountryRegion.show shippingCountryView
 @layout.billingCountryRegion.show billingCountryView

所以它似乎是一个非常缓慢的渲染问题。

 Show.Controller =
  showProfile: ->
    @layout = @getLayoutView()

    @layout.on "show", =>
      headerView = @getHeaderView()
      @layout.headerRegion.show headerView

      accessView = @getAccessView()
      @layout.accessRegion.show accessView

      billingReadmeView = @getBillingReadmeView()
      @layout.billingReadmeRegion.show billingReadmeView

      billingFieldsView = @getBillingFieldsView()
      @layout.billingFieldRegion.show billingFieldsView

      shippingReadmeView = @getShippingReadmeView()
      @layout.shippingReadmeRegion.show shippingReadmeView

      shippingFieldsView = @getShippingFieldsView()
      @layout.shippingFieldRegion.show shippingFieldsView

      MyApp.request "location:get_countries", (countries) =>
        billingCountryView = @getBillingCountryView(countries)
        @layout.billingCountryRegion.show billingCountryView

      MyApp.request "location:get_states", MyApp.activeCustomer.get('billing_country_id'), (states) =>
        billingStateView = @getBillingStatesView(states)
        @layout.billingStateRegion.show billingStateView

      MyApp.request "location:get_countries", (countries) =>
        shippingCountryView = @getShippingCountryView(countries)
         @layout.shippingCountryRegion.show shippingCountryView

      MyApp.request "location:get_states", MyApp.activeCustomer.get('shipping_country_id'), (states) =>
        shippingStateView = @getShippingStatesView(states)
        @layout.shippingStateRegion.show shippingStateView

    MyApp.mainRegion.show @layout

结算国家/地区视图:

class View.BillingCountryDropdownItem extends MyApp.Views.ItemView
  template: billingCountryItemTpl
  tagName: "option"

  onRender: ->
    this.$el.attr('value', this.model.get('id'));
    if MyApp.activeCustomer.get('billing_country_id') == this.model.get('id')
      this.$el.attr('selected', 'selected');

class View.BillingCountryDropdown extends MyApp.Views.CompositeView
  template: billingCountryTpl
  itemView: View.BillingCountryDropdownItem
  itemViewContainer: "select"

模板,简单地说:

        <label>Country
        <select id="billing_country_id" name="billing_country_id">
           <%- name %>
        </select>
    </label>

3 个答案:

答案 0 :(得分:1)

您的代码可以进行优化。只需将onRender方法的内容移至ItemView属性。

class View.BillingCountryDropdownItem extends MyApp.Views.ItemView
  template: billingCountryItemTpl
  tagName: "option"

  attributes: -> 
    var id = this.model.get('id'); 
    var attributes = { 'value': id };
    if MyApp.activeCustomer.get('billing_country_id') == this.model.get('id')
      attributes['selected'] =  'selected';
    return attributes 

此方法与onRender情况之间的区别在于,渲染将在集合已经呈现时执行,并且将使用DOM节点完成200多个操作,这将带来性能问题。

对于attributes方法,它在视图创建时执行。

答案 1 :(得分:0)

您可以遵循的建议很少:

1)问你自己你真的需要一次渲染所有物品吗?也许你可以渲染部分集合并渲染其他项目滚动或使用分页或使用虚拟scrioll&#39;以SlickGridWebix为例。

2)查看重新渲染视图的频率。尝试缩小导致重新渲染的事件数量

3)尝试缩小ItemView的事件侦听器数量。将上下文事件委托给CollectionView

的好习惯

4)您可以使用setTimeout按部件呈现集合。例如,你将4个部分中的coll除以50个项目,并提出4个超时来渲染它。

5)您可以优化下划线模板并摆脱with {}运算符。 http://underscorejs.org/#template

答案 2 :(得分:0)

您的'结算国家/地区ItemTpl'变量中包含哪些内容?如果它只是带有模板ID的字符串,那么您可以使用Marionette.TemplateCache预编译模板。

所以你会:

template: Marionette.TemplateCache.get(billingCountryItemTpl)