【发布时间】:2014-10-12 01:25:37
【问题描述】:
我目前正在开发一个项目,该项目在后端使用 .NET MVC,在前端使用 Backbone (v1.1) 和 Marionette JS (v1.8.5),我在尝试渲染时遇到了一些性能问题具有 200 个结果或项目视图的复合视图。
我第一次遇到this SO post of a similar issue,它帮助我获得了更新版本的木偶(v1.8.5)。
Handlebars 模板用于显示一个 html 表格,其中每个 itemView 都包装在一个 tbody 中(其中有一个更复杂的手风琴视图,因此使用的是 tbody 而不是更具语义的 tr)
Composite 视图正在初始化,并在其子应用程序初始化时显示在 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 缓冲区。通过调试,我认为这是因为在获取之前使用空的活动集合实例化了视图,所以 Marionette 认为我正在更新集合并将 isBuffering 设置为 false。
我也尝试过像这样在获取成功回调中实例化活动视图;
activities.fetch({
success: function(newCollection) {
module.activitiesView = new Views.ActivitiesView({
collection: newCollection
});
App.RegionActivities.show(module.activitiesView);
}
});
这确实将 200 个项目附加到集合 elBuffer(大约需要 4 秒),但在屏幕上显示任何内容之前需要另外 50 秒左右。调试表明由集合触发的 onShow 方法可能会导致此延迟,因为它会逐个循环遍历每个项目。
我错过了什么吗?
我是否在正确的地方做所有事情?
我正在努力实现的目标是否可能?
我觉得很奇怪,这可能如此困难。
感谢您的宝贵时间。 汤姆
编辑
这里是复合视图和项目视图模板。
Activity 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>
Activity 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 tools javascript CPU profile 的结果:
前 3 项均指 Marionette triggerMethod 占用 80% CPU。
【问题讨论】:
-
你能发布模板吗?这应该没什么区别,但试试
activities.fetch().done(function() { App.RegionActivities.show(module.activitiesView); }) -
感谢@Meistro,但不幸的是这并没有帮助。我现在正在使用我的问题中的第二个版本,我在其中执行提取,然后成功实例化视图。 Console.logging activiesView 实例发生在第二次。问题似乎与在屏幕上呈现集合有关。主要通过 region.show()
-
你能发布你的
onShow函数吗?我不明白为什么调用该函数几百次会导致您出现问题(50 秒延迟)。您的模板似乎也很简单。我有一个应用程序,它非常相似地插入了 200 项长的列表,并且看不到您遇到的那种性能问题。这个等式缺少一些东西。 -
另外,当您深入了解配置文件的
triggerMethod部分时,您要获得什么功能,这是您自己的代码? -
@AndrewHubbs 我没有在我的复合视图或项目视图中使用 onShow 函数。关于 devtools 配置文件,我会回复你。我从记忆中没有注意到与我自己的代码有关的任何内容
标签: javascript performance backbone.js marionette backbone-views