CompositeView slow to render items for large result set Marionette

删除回忆录丶 提交于 2019-12-10 17:22:30

问题


I'm currently working on a project that's using .NET MVC on the back end and Backbone (v1.1) with Marionette JS (v1.8.5) on the front end and I am experiencing some performance issues when trying to render a Composite view with 200 results or item views.

I first came across this SO post of a similar issue which helped me get a newer version of marionette (v1.8.5).

Handlebars templates are being used to show a html table with each itemView being wrapped in a tbody (this has a more complex accordion view within it hence tbody being used rather than a more semantic tr)

The Composite view is being initialised and shown in a Marionette region when it's sub app is initialised.

Here's a simplified version of my code.

Activities sub app

'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();

});

Activities Composite View

'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

});

Activities Item View

'use strict';

Views.ActivityView = Backbone.Marionette.ItemView.extend({

    template: Handlebars.templates['activities/activity'],

    tagName: 'tbody'

});

I read the Marionette Docs on the better performing doc fragment

So the performance issue that I'm having is that all 200 items are being appended one at a time and not utilising docFragment buffer. Through debugging I believe this is because the view is being instantiated with an empty Activities collection before the fetch, so Marionette thinks I'm updating the collection and sets the isBuffering to false.

I've also tried instatiating the activitiesView inside the fetch success callback like so;

activities.fetch({
    success: function(newCollection) {
        module.activitiesView = new Views.ActivitiesView({
            collection: newCollection
        });

        App.RegionActivities.show(module.activitiesView);
    }
});

This does append the 200 items to the collections elBuffer (takes about 4 seconds) but then takes another 50 seconds or so before anything is shown on screen. Debugging suggests the onShow method that's triggered by the collection could be causing this delay as it loop through each item one by one.

Have I missed something?

Am I doing everything in the right places?

Is what I'm trying to achieve even possible?

Seems strange to me that this could be so difficult.

Thanks for you time. Tom

Edit

Here are both the composite view and item view templates.

Activities CompositeView template

<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 template (each wrapped in 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>

Update

Results from chrome dev tools javascript CPU profile:

Top 3 items all refer to Marionette triggerMethod taking up 80% of CPU.

Full sized image at: http://i.stack.imgur.com/JjT3Z.png


回答1:


The buffer will be used when the collection is reset, so you could try

activities.fetch({reset: true});

The other option is to wait until the fetch is done (using deferreds/promises) before initializing and displaying your view.



来源:https://stackoverflow.com/questions/25375045/compositeview-slow-to-render-items-for-large-result-set-marionette

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!