CompositeView缓慢渲染大型结果集Marionette的项目

时间:2014-08-19 02:56:08

标签: javascript performance backbone.js marionette backbone-views

我目前正在开发一个在后端使用.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。

Dev tools CPU Profile Drilldown

全尺寸图片位于:http://i.stack.imgur.com/JjT3Z.png

1 个答案:

答案 0 :(得分:3)

重置集合时将使用缓冲区,因此您可以尝试

activities.fetch({reset: true});

另一种选择是在初始化和显示视图之前等待提取完成(使用deferreds / promises)。