2016-05-27 39 views
5

Sono nuovo in Ember.js e ho riscontrato problemi di prestazioni durante il tentativo di creare migliaia di record (5300 per la precisione) e aggiornare una relazione hasMany. Sto facendo una richiesta alla mia API per recuperare i record prima di creare i miei nuovi record. Dopo che la promessa è tornata, eseguo una correzione su ogni record riportato in basso (5300) per eseguire i miei calcoli per il nuovo set di record. La creazione dei record richiede circa 2 secondi. Aggiornamento di hasMany inizia rapidamente solo per i primi 40 o più record e quindi rallenta a circa un aggiornamento al secondo.Ember.js/Ember I dati impiegano diversi minuti per l'aggiornamento di molti genitori dopo aver creato migliaia di record figlio

Devo anche notare che questo viene fatto all'interno di un componente. So che questo è tipicamente anit-pattern, ma in questo caso non c'è motivo di cambiare l'URL o la transizione. Questa è una schermata in cui gli utenti possono selezionare da un gruppo di elementi (forniti dalla rotta), applicare una regola di determinazione del prezzo e quindi creare un evento (creato nel percorso) in base a tali elementi. È una sandbox per determinare quali oggetti faranno parte dell'evento. Una volta che gli utenti hanno deciso i loro articoli per l'evento, quindi invio un'azione al percorso per eseguire il salvataggio effettivo e persistere nel mio back-end. Al di fuori dell'aspetto anti-pattern, non riesco a vedere come ciò influirebbe sulle prestazioni dell'aggiornamento hasMany.

Sto usando RESTAdapter e RESTSerializer per quello che vale, ma questo non dovrebbe avere alcun impatto qui dato che mi sto occupando solo del data store di Ember.

Ember Versione:

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

I due modelli in questione sono i seguenti ...

Bambino Modello (evento-voce):

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 Girl (evento):

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

Evento creare registrazione:

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

blocco di codice nella componente responsabile della creazione e l'aggiornamento di record 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'); 
}); 

Finora ho provato quanto segue ...

  • Aggiunta inversa relazioni con myMany e appartiene a
  • Aggiungendo tutti i record di creazione a un Ember.A() e quindi cercando di spingere il nuovo record per l'hasMany in questo modo: this.get('event').get('eventItems').pushObjects(newEventItems);. Anche provato usando this.get('event').get('eventItems').addObjects(newEventItems);.
  • Impostazione di appartiene al record che si sta creando anziché aggiornare hasMany del genitore (evento).
  • Sono anche andato avanti e ho spostato questa logica nel mio percorso solo per assicurarsi che non stavo ottenendo un comportamento strano facendo questo nel componente. Funziona allo stesso modo.

Suppongo (e, per favore, correggimi se sbaglio) che la creazione di record e l'aggiornamento delle relazioni strettamente sul lato client dovrebbero essere in grado di gestire migliaia di record senza troppi problemi. Spero che sto solo facendo qualcosa di sbagliato o in un modo inefficiente che sarà ovvio per qualcuno con più esperienza. Qualsiasi aiuto, comprese le alternative, è molto apprezzato!

+0

In quale browser si sta verificando? – Terseus

+0

@Terseus, Chrome, versione 49.0.2623.75 m –

risposta

0

Ho trovato che lavorare con gruppi di grandi dimensioni di relazioni "hasMany" è lento.

Il mio consiglio: Creare la relazione sul server con un endpoint personalizzato e comunicare le modifiche al client tramite websocket. Cercando di salvare individualmente i record 5300 in Ember, verranno eseguite 5300 richieste di rete, mentre ciò potrebbe essere ottenuto in 1 richiesta in uscita e, eventualmente, in un messaggio Websockets, anche se potrebbe essere consigliabile raggruppare le risposte in serie più piccole.

Nessuna necessità di creare relazioni in Ember fino a quando le modifiche non vengono confermate. Il messaggio Websockets restituito dovrebbe includere le chiavi esterne della relazione. Ember Data deve costruire le relazioni.

Ciò significa che in primo piano, verrà creato eventItems (o qualsiasi altro modello venga chiamato) senza un genitore.

Infine, si potrebbe considerare di creare i record figlio su richiesta, invece di provare a creare immediatamente ogni elemento figlio per l'utente. Basta fare il createRecord quando un utente decide di selezionare l'articolo dal gruppo di articoli. (Spero di aver compreso correttamente il tuo caso d'uso.) Se segui questo approccio, potresti non aver nemmeno bisogno di usare un endpoint personalizzato come ho descritto.

ultimo consiglio: il messaggio relativo a 'anti-pattern' è corretto: non fare mai le operazioni CRUD, o qualcosa di veramente asincrono, nei componenti, in particolare non per 5300 articoli. I componenti possono essere facilmente abbattuti prima che l'operazione asincrona venga completata, lasciando l'applicazione in uno stato strano e molto probabilmente causando errori. Muovi qualunque cosa tu faccia nel percorso, come hai detto tu, e segui quel modello. I componenti dovrebbero essere solo modelli "stupidi" che mostrano elementi e inviano azioni.