当显示大约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>
您的代码可以优化。只需将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)