提问者:小点点

主干木偶图慢速复合视图(200个集合)


当显示大约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个答案

匿名用户

您的代码可以优化。只需将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情况的区别在于,当集合已渲染时,将执行onRender,并且将使用DOM节点执行200个操作,这将带来性能问题。

属性方法的情况下,它在创建视图时执行。

匿名用户

您可以遵循以下几点建议:

1) 问问你自己,你真的需要一次渲染所有项目吗?例如,您可以渲染集合的一部分并在滚动上渲染其他项目,或者使用分页,或者使用带有SlickGrid或Webix的“virtual scrioll”。

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

3)尝试缩小ItemView的事件监听器数。它的良好实践委托上下文事件集合视图

4) 您可以使用setTimeout按部分渲染集合。例如,将coll分成4个部分,再除以50个项目,然后引发4个超时以渲染它。

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

匿名用户

您的“billingCountryItemTpl”变量中有什么?如果它只是带有模板ID的字符串,那么可以使用木偶预编译模板。模板缓存。

因此,您将有:

template: Marionette.TemplateCache.get(billingCountryItemTpl)