2016-05-27 2 views
5

Я новичок в Ember.js и сталкиваюсь с проблемами производительности при попытке создания тысяч записей (точнее, 5300) и обновление отношений hasMany. Я делаю запрос к моему API для получения записей, прежде чем создавать свои новые записи. После того, как обещание вернется, я затем сделаю forEach по каждой записи, сбитой (5300), чтобы выполнить мои вычисления для нового набора записей. Создание самих записей занимает около 2 секунд. Обновление hasMany быстро запускается только для первых 40 или около того записей, а затем замедляется примерно до одного обновления в секунду.Ember.js/Ember Данные занимают несколько минут, чтобы обновить hasMany родителя после создания тысяч дочерних записей

Следует также отметить, что это выполняется внутри компонента. Я знаю, что это обычно anit-pattern, но в этом случае нет причин изменять URL-адрес или переход. Это экран, на котором пользователи могут выбирать из пула элементов (предоставляемых по маршруту), применять правило ценообразования и затем создавать событие (созданное на маршруте) на основе этих элементов. Это песочница, чтобы определить, какие предметы будут частью мероприятия. После того, как пользователи определили свои элементы для события, я затем отправляю действие по маршруту, чтобы выполнить фактическое сохранение и сохранить его на моем сервере. Вне аспекта анти-шаблона я не вижу, как это повлияет на производительность обновления hasMany.

Я использую RESTAdapter и RESTSerializer для того, что это стоит, но это не должно иметь никакого влияния здесь, так как я просто имею дело с хранилищем данных Ember.

Ember Версия:

Ember    : 2.5.1 
Ember Data  : 2.5.3 
jQuery   : 2.2.3 
Ember Simple Auth : 1.1.0 

Две модели в вопросе являются следующие ...

Child Model (событие-пункт):

export default DS.Model.extend({ 
    event: DS.belongsTo('event'), 
    itemNumber: DS.attr('string'), 
    styleNumber: DS.attr('string'), 
    tier: DS.attr('string'), 
    eventPrice: DS.attr('number') 
}); 

Родитель модель (событие):

export default DS.Model.extend({ 
    eventTypeId: DS.attr('string'), 
    eventName: DS.attr('string'), 
    eventDesc: DS.attr('string'), 
    startDate: DS.attr('moment-date'), 
    endDate: DS.attr('moment-date'), 
    priority: DS.attr('number'), 
    statusCode: DS.attr('string'), 
    value: DS.attr('number'), 
    eventItems: DS.hasMany('event-item', {async:true}) 
}); 

событий создать запись:

model() { 
    return this.store.createRecord('event', {}); 
}, 

код блока в компонент отвечает за создание записей и обновление hasMany:

this.get('store').query('pricing', {brandCd: '00'}).then(tiers => { 
    tiers.forEach(tier => { 
     this.get('event').get('eventItems').createRecord({ 
      styleNumber: tier.get('styleNumber'), 
      itemNumber: tier.get('itemNumber'), 
      brandCd: '00', 
      tier: tier.get('tier'), 
      eventPrice: this._calculateEventPrice(tier.get('origPrice'), this.get('event').get('eventTypeId'), this.get('event').get('value')), 
     }); 
    }); 

    this.get('event').set('needsUpdated', 'Y'); 
}); 

До сих пор я попытался следующие ...

  • Добавление обратного отношения с моим hasMany и принадлежит
  • Добавление всех записей создания в Ember.A(), а затем попытка нажать новый записей в hasMany, например: this.get('event').get('eventItems').pushObjects(newEventItems);. Также попробовал это с помощью this.get('event').get('eventItems').addObjects(newEventItems);.
  • Установка права собственности на запись, создаваемую вместо обновления hasMany родителя (события).
  • Я также пошел дальше и переместил эту логику в свой маршрут, чтобы убедиться, что я не получаю странное поведение, выполнив это в компоненте. Он выполняет то же самое.

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

+0

В каком браузере вы тестируете это? – Terseus

+0

@Terseus, Chrome, версия 49.0.2623.75 m –

ответ

0

Я нашел работу с большими наборами отношений hasMany также медленными.

Мой совет: Создайте отношения на сервере с пользовательской конечной точкой и сообщите изменения клиенту по веб-окнам. Попытка индивидуально сохранить 5300 записей в Ember сделает 5300 сетевых запросов, в то время как это может быть выполнено в 1 исходящем запросе и, возможно, в одном сообщении с веб-серверами, хотя может быть целесообразно выполнить партию ответов в меньших наборах.

Не нужно устанавливать отношения в Ember до тех пор, пока изменения не будут выполнены. Возвращенное сообщение websockets должно включать внешние ключи отношения. Ember Data должен построить отношения.

Это означает, что перед вами будет создаваться eventItems (или что бы вы ни называли вашу модель) без родителя.

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

последний совет: Ваши заметки о «анти-шаблоны» правильно: НИКОГДА не делать CRUD операции, или что-нибудь действительно асинхронной, в компонентах, особенно не для 5300 пунктов. Компоненты можно легко снести до завершения асинхронной операции, оставив приложение в странном состоянии и, скорее всего, приведет к ошибкам. Переместите все, что вы делаете на маршрут, как вы сказали, и придерживайтесь этого шаблона. Компоненты должны быть просто «тупыми» шаблонами, отображающими материал и отправляющими действия.

Смежные вопросы