Search code examples
javascripthtmlbackbone.jsejsbackbone-views

Backbone view takes some time to load when new data is added to the collection


I am new to backbone and working on a CMS built in backbone. The CMS allows the creators to add new homepages for the website. The size of the response for 50 items from the API is about 25mb. My HTML page has a load button which fires a event and loads 50 more items when it is clicked. The problem that I am facing is that the view takes some time to load when ever the click is fired i.e the view disappears and the user forgets where he was before the loading of the view. Is there a way to make it make the view rendering much faster so it does not disappear and the user can remember where exactly he was. The event to load more data is fired when button with class load-more is clicked. Here is some part of my code. The view:

cms.views.Homepages = Backbone.View.extend({

events: {
'click .filter li': 'filterArticles',
'click .list-column-title' : 'openLink',
'click .homepageAction': 'updateHomepageStatus',
'click .more-actions .delete': 'deleteHomepage',
'click .more-actions .duplicate': 'duplicate',
'click .editPubDate': 'editPubDate',
'click .next': 'nextItems',
'click .prev': 'prevItems',
'click .load-more': 'loadMore'
 },  initialize: function(homepages, articles) {

this.template = new EJS({url: 'app/views/root/homepages/homepages.template.ejs'});
this.homepagesTableTemplate = new EJS({url: 'app/views/root/homepages/homepages-table.template.ejs'});
this.listenTo(cms.data.homepages, 'loaded', this.displayTable,this.render);
cms.data.homepages.load();


this.listenTo(cms.data.homepages, 'nomoreload', this.disableMoreLoad)

this.initDialogs();}, 


 render: function(options) {

var html = this.template.render({homepages: cms.data.homepages.toJSON()});
this.$el.html(html);
return this;
 },

loadMore: function(e) {
e.preventDefault();

this.collection.loadMore();
//this.collection.reset(newmodel.loadMore());
console.log( this.collection);}

The code in my collection

cms.collections.HomePages = Backbone.Collection.extend({

 model: cms.models.HomePage,

 currentPage: 0,

 url: function () {
//console.log(this,  this.currentPage )
return cms.config.BASE_URL + 'cms/homepage?page=' + this.currentPage + '&per_page=50&filter[sort]=creationdate_desc'
},
loadMore: function() {
this.currentPage ++;
var self = this;
 this.fetch({
  success: function(collection, response) {
    self.trigger('loaded', null);
    // if response less than 50 -> end of load      
    console.log(collection);

    if (response.length === 0) {
      self.trigger('nomoreload', null);
    }

  },
  error: function() {
    self.trigger('loaded', true);
  },
  remove: false
});

Solution

  • As Emile Bergeron rightly mentioned, 25 MB is a lot of data on a homepage. In this situation, you will have to optimize your code so as to get response in chunks and show only what is required to the user.
    Another approach is store a certain amount of data in a Web worker so you can provide a chunk of that data directly from there avoiding a network call. Fetch new data as and when required and store it in your web worker by clearing the previous stale data.