vendredi 27 mai 2016

Ember.js/Ember Data takes several minutes to update hasMany of parent after creating thousands of child records

I'm new to Ember.js and running into performance issues when trying to create thousands of records (5300 to be exact) and updating a hasMany relationship. I'm making a request to my API to retrieve records before I create my new records. After the promise returns, I then do a forEach over each record brought down (5300) to do my calculations for the new set of records. Creating the records themselves takes about 2 seconds. Updating the hasMany starts off quickly only for the first 40 or so records and then slows to about one update per second.

I should also note that this is being done within a component. I know this is typically anit-pattern, but in this case there is no reason to change the URL or transition. This is a screen where users can select from a pool of items (provided by the route), apply a pricing rule, and then create an event (created in the route) based on those items. It's a sandbox to determine what items will be a part of the event. Once the users have decided on their items for the event, I then send an action up to the route to perform the actual save and persist to my backend. Outside of the anti-pattern aspect, I can't see how this would affect the performance of the hasMany update.

I'm using RESTAdapter and RESTSerializer for what it's worth, but that should not have any impact here since I'm just dealing with the Ember data store.

Ember Version:

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

The two models in question are as follows...

Child Model (event-item):

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

Parent Model (event):

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

Event create record:

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

Code block in component responsible for creating records and updating 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');
});

So far I've tried the following...

  • Adding inverse relationships to my hasMany and belongsTo
  • Adding all of the create records to an Ember.A() and then trying to push the new records to the hasMany like so: this.get('event').get('eventItems').pushObjects(newEventItems);. Also tried it using this.get('event').get('eventItems').addObjects(newEventItems);.
  • Setting the belongsTo on the record being created instead of updating the hasMany of the parent (event).
  • I also went ahead and moved this logic into my route just to make sure I wasn't getting odd behavior by doing this in the component. It performs the same.

I would assume (and please correct me if I'm wrong) that creating records and updating relationships strictly on the client side should be able to handle thousands of records without too much issue. I'm hoping I'm just doing something incorrect or in an inefficient way that will be obvious to someone with more experience. Any help, including alternatives, is greatly appreciated!




Aucun commentaire:

Enregistrer un commentaire