我目前正在开发一个在后端使用.NET MVC的项目和在前端使用Marionette JS(v1.8.5)的Backbone(v1.1),我在尝试渲染时遇到一些性能问题具有200个结果或项目视图的复合视图。
我第一次遇到this SO post of a similar issue帮助我获得了更新版的牵线木偶(v1.8.5)。
Handlebars模板用于显示一个html表,每个itemView都包含在一个tbody中(这里有一个更复杂的手风琴视图,因此使用了tbody而不是更多的语义tr)
复合视图正在初始化,并在初始化子应用程序时显示在Marionette区域中。
这是我的代码的简化版本。
活动子应用
'use strict';
App.module('Activities', function(){
this.startWithParent = false;
});
App.addRegions({
RegionActivities: '#region-Activities' // <= this lives in .NET View of project
});
App.Activities.addInitializer(function (options) {
var module = this,
activities = new Collections.Activities();
module.activitiesView = new Views.ActivitiesView({
collection: activities
});
App.RegionActivities.show(module.activitiesView);
activities.fetch();
});
活动综合视图
'use strict';
Views.ActivitiesView = Backbone.Marionette.CompositeView.extend({
template: Handlebars.templates['activities/activities'],
itemView: Views.ActivityView,
itemViewContainer: '.admin-table--activities', // <= html table that items are appended to
});
活动项目视图
'use strict';
Views.ActivityView = Backbone.Marionette.ItemView.extend({
template: Handlebars.templates['activities/activity'],
tagName: 'tbody'
});
我读了Marionette Docs on the better performing doc fragment
所以我遇到的性能问题是所有200个项目一次添加一个而不使用docFragment缓冲区。通过调试我相信这是因为在获取之前,视图正在使用空的Activities集合进行实例化,因此Marionette认为我正在更新集合并将isBuffering设置为false。
我也尝试在fetch成功回调中设置activitiesView,就像这样;
activities.fetch({
success: function(newCollection) {
module.activitiesView = new Views.ActivitiesView({
collection: newCollection
});
App.RegionActivities.show(module.activitiesView);
}
});
这会将200个项目附加到集合elBuffer(大约需要4秒),但是在屏幕上显示任何内容之前需要再过50秒左右。调试表明由集合触发的onShow方法可能导致此延迟,因为它逐个循环遍历每个项目。
我错过了什么吗?
我是否在适当的地方做所有事情?
我正在努力实现的目标是什么?
我觉得很奇怪,这可能很难。
谢谢你的时间。 汤姆
修改的
以下是复合视图和项目视图模板。
活动CompositeView模板
<table class="admin-table admin-table--accordion admin-table--activities">
<colgroup>
<col width="10%">
<col width="22%">
<col width="23%">
<col width="23%">
<col width="22%">
</colgroup>
<thead>
<tr>
<th>Type</th>
<th>Vessel</th>
<th>Activity</th>
<th>Information</th>
<th>Review Status</th>
</tr>
</thead>
</table>
活动ItemView模板(每个包裹在tbody中)
<tr class="table-title">
<td>Col 1 data</td>
<td>Col 2 data</td>
<td>Col 3 data</td>
<td>Col 4 data</td>
<td Col 5 data</td>
</tr>
<tr class="table-content">
<td colspan="5">More info in here...</td>
</tr>
更新
chrome dev工具的结果javascript CPU个人资料:
前3项都是指Marionette triggerMethod占据80%的CPU。
答案 0 :(得分:3)
重置集合时将使用缓冲区,因此您可以尝试
activities.fetch({reset: true});
另一种选择是在初始化和显示视图之前等待提取完成(使用deferreds / promises)。