Большая коллекция Backbone.js fetch () приводит к зависанию скрипта - PullRequest
6 голосов
/ 21 января 2012

У меня есть табличное представление Jobs, которое отображает все задания пользователя.Функция fetch () коллекции Jobs может возвращать тысячи записей.Я запустил тест и вставил 1000 записей заданий в базу данных и выполнил выборку () для коллекции.Однако 1000 записей кажутся слишком большими для браузера, так как вставка 1000 строк таблицы DOM, по-видимому, приводит к зависанию браузера.

Есть ли лучший способ оптимизировать рендеринг строк, чтобы он работал быстрее?Я знаю, что вы всегда можете выполнить частичную выборку (выборку вначале 100 записей и дополнительно выборку 100 записей каждый раз, когда пользователь прокручивает страницу вниз), но я, как правило, против этой идеи, поскольку прокручиваю 100 записей и приходится ждать-4 секунды до рендеринга дополнительных 100 записей, похоже, приводят к ухудшению работы пользователя.

Вот мой код:

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;
  }

});

Ответы [ 2 ]

5 голосов
/ 21 января 2012

все зависит от того, какой опыт нужен пользователю, что он будет делать с заданиями, Ваш пользователь, это потенциальный кандидат на работу, который ищет определенную работу? или это своего рода приложение для администрирования, где пользователь - это тот, кто управляет работой?

В общем, размещение 1000 элементов на 1 странице - это плохой опыт, работа с загрузкой дополнительных заданий при прокрутке вниз - это популярная функция в наши дни, например, Facebook, Twitter ... это может быть полезно для комментариев, но задания - это что-то другое, нужно прыгать от начала до конца, не нажимая «больше» 10 раз, или прокручивая вниз 10 раз.

возможные решения:

  1. так что пейджинг - это, конечно, еще один вариант, использование пейджера, безусловно, является способом работы со слишком большим количеством элементов и дает человеку возможность переходить со страницы 1 на 10, не проходя через 9 других.
  2. еще одна вещь, которую вы можете сделать, это встроить фильтры, можно искать работу по: местоположению, фирме, сектору, ... это уменьшит размер коллекции, которая видна постоянно.

чисто технические решения:

вы должны прочитать это сообщение в блоге , оно начинается с того, как получить точно выбранный элемент из представления, если вы отобразили все элементы коллекции всего за 1 просмотр, но развивается в проблему на рука здесь, добавление 1000 отдельных представлений по 1 для каждого задания в jobListView или добавление этих заданий в jobListView, чтобы было только 1 представление.

Последнее может, если реализовано правильно, значительно снизить взаимодействие вашего приложения с DOM. С правильно реализованным я имею в виду добавление всех заданий в цикле for, добавление их в таблицу / список в памяти и только в самом конце присоединение таблицы / списка к DOM, это сокращает ваш код до 1 взаимодействия DOM , а не 1000 добавляет.

Да, Дерик больше склоняется к визуализации 1 вида на модель, хотя он не затрагивает тему производительности, за исключением небольшого: сначала сделайте это, а затем сделайте это быстро, что не дает никаких решений для вас. И если ваш список вакансий - это просто список и ссылка на страницу сведений о работе без большого количества событий, опция просмотра всех их по-прежнему остается верной.

2 голосов
/ 22 января 2012

Ваша низкая производительность, вероятно, связана с тем, что вы добавляете строки непосредственно в DOM.Каждый раз, когда вы делаете это, браузер будет перекомпоновываться.

Я бы построил таблицу в памяти, а затем добавил бы всю таблицу в DOM, как только она будет создана.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...