Backbone.js fetch () large collection calls script to freeze

I have a Jobs table view that displays all user tasks. Collection of data from collection () may potentially return containing thousands of records. I checked the test and inserted 1000 work records in the database and fetch () in the collection. However, 1000 entries seem too large for the browser to process, since inserting rows from the 1000 DOM table seems to cause the browser to freeze.

Is there a better way to optimize the rendering of strings so that it works faster? I know that you can always perform partial sampling (sampling for 100 records and additionally sampling 100 records each time the user scrolls to the bottom of the screen), but I am usually against this idea, since scrolling 100 records and having to wait 3 4 seconds before the extra 100 entries seem to be causing poor user experience.

Here is my code:

FM.Views.JobTable = Backbone.View.extend({ initialize: function(){ _.bindAll(this, 'render', 'refresh', 'appendItem'); this.collection.bind('add', this.appendItem, this); this.collection.bind('reset', this.refresh, this); }, render: function(){ this.el = ich.JobTable({}); $(this.el).addClass('loading'); return this; }, refresh: function(){ $('tbody tr', this.el).remove(); $(this.el).removeClass('loading'); _(this.collection.models).each(function(item){ // in case collection is not empty this.appendItem(item); }, this); return this; }, appendItem: function(item){ var jobRow = new FM.Views.JobTableRow({ model: item }); $('tbody', this.el).prepend(jobRow.render().el); $(jobRow).bind('FM_JobSelected', this.triggerSelected); } }); FM.Views.JobTableRow = Backbone.View.extend({ tagName: 'tr', initialize: function(){ _.bindAll(this, 'render', 'remove', 'triggerSelected'); this.model.bind('remove', this.remove); }, render: function(){ var j = this.model.toJSON(); j.quantity = j.quantity ? number_format(j.quantity, 0) : ''; j.date_start = date('M j Y', j.date_start); j.date_due = j.date_due ? date('M j Y', strtotime(j.date_due)) : ''; j.paid_class = j.paid; j.status_class = j.status; j.paid = slug2words(j.paid); j.status = slug2words(j.status); this.el = ich.JobTableRow(j); $(this.el).bind('click', this.triggerSelected); return this; } }); 
+6
source share
2 answers

it all depends on what kind of experience the user needs, what he will do with the tasks, is your user a potential job candidate looking for a specific job? or is it some kind of administration application where the user manages tasks?

in general, laying 1000 items on 1 page is a bad user experience, working with downloading additional tasks to scroll down is such a hot function these days as facebook, twitter ... it can be useful for comments, but jobs - this is something else, you need to go from beginning to end without pressing β€œmore” 10 times or scrolling down 10 times.

possible solutions:

  • Thus, paging is, of course, another option, using a pager is a protective way to work with too many elements and allows a person to go from page 1 to 10 without going through 9 others.
  • Another thing you can do is create filters, you can search for jobs by: location, firm, sector, ... this will reduce the size of the collection, which will be visible at any time.

purely technical solutions:

you should read this blog post , it starts on how to get an exact click of an element from the view, if you have selected all the elements the collection is just 1 look, but develops in this matter, having 1000 separate views 1 for each job added to jobListView or having these jobs added to jobListView, so there is only 1 view.

The latter can be implemented correctly, significantly reducing the interaction of your application with the DOM. With the implementation correctly, I mean, adding all the tasks to the for loop, adding them to the table / list in memory, and only at the very end attach the table / list to the DOM, this reduces your code to 1 interaction with the DOM, not 1000 applications .

Yes, Derik is more focused on rendering 1 view of the model, although he does not touch on the topic of performance, with the exception of a small one: first, make sure he quickly makes an operator that does not provide you with any solutions. And if your list of tasks is just a listing and a link to the details page of the task, without any events, the "1 view for everyone else" option is still very important.

+5
source

Your poor performance is probably due to the fact that you are adding lines directly to the DOM. Every time you do this, the browser will be rescheduled.

I would build the table in memory, and then add the whole table to the DOM after creating it.

+2
source

Source: https://habr.com/ru/post/906543/


All Articles