2013-02-08 13 views
6

Ho un'app Web che esegue una richiesta SOAP per alcuni dati e compila un viewmodel a eliminazione diretta con i risultati. Attualmente sto recuperando circa 1000 elementi pubblicitari che devono essere inseriti nel mio modello a eliminazione diretta. Il profiling della pagina in chrome mostra che una grande parte del tempo di caricamento/CPU è spesa in knockout.js. Sto vagando se c'è un modo per rimandare eventuali aggiornamenti/elaborazioni ad eliminazione diretta fino a quando tutti gli elementi non vengono inseriti nell'array osservabile.Posso accelerare il knockout quando si popola un array osservabile di grandi dimensioni?

Modifica: Per essere più chiaro, suppongo che sto cercando qualcosa come il ritardo o throttling. Ma sembra che, dal this answer, stia solo migliorando la costruzione di un array normale e poi popolando l'intero array osservabile, invece di spingere ogni elemento direttamente sull'array osservabile. Ciò potrebbe rimuovere la necessità di ritardare o limitare i binding. Qualche consiglio?

+0

Si sta utilizzando ko.mapping? – delixfe

risposta

10

Se è sufficiente sostituire il contenuto di uno observableArray, non è necessario eseguire il ciclo attraverso l'array.

L'operazione più efficace è quello di impostare semplicemente ad un nuovo valore:

this.obsArray(newData); 
+0

Questo ha funzionato bene. Grazie. – xdumaine

1

Forse un'altra soluzione è inserire gli elementi dall'array, nell'array osservabile da blocchi di 20 o 50 elementi?

Dato che si aggiungeranno elementi a un campo visibile, a eliminazione diretta verranno visualizzati mentre li si aggiunge, ma potrebbe aiutare a ridurre la quantità di CPU necessaria, poiché sarà possibile aggiungere un ritardo tra ogni blocco.

Potrebbe valere la pena provare.

5

sto tirando circa 850 articoli nel mio modello di vista e la loro visualizzazione in un prescelto. L'introduzione di un ciclo ha richiesto circa 15 secondi e ha subito un degrado lineare.

ho usato la soluzione valueHasMutated qui: http://www.knockmeout.net/2012/04/knockoutjs-performance-gotcha.html

giù a circa 200 ms (nel complesso - compresi andata e ritorno al server, db lettura, ecc)

+0

La soluzione in questa pagina offre un incredibile incremento delle prestazioni, grazie per il regalo di Natale :) So che è in ritardo di 2 anni, ma se sei ancora attivo considera copia/incolla il codice, quindi se la pagina non è in linea lo abbiamo ancora a il nostro smaltimento .. – Sam

+0

Se va offline, dovresti comunque essere in grado di vederlo tramite archive.org ... https://web.archive.org/web/20150812144018/http://www.knockmeout.net/2012 /04/knockoutjs-performance-gotcha.html –

+1

Mentre preferirei cadere in una discussione, sono rispettosamente in disaccordo. Consulta il paragrafo http://stackoverflow.com/help/how-to-answer "Fornisci il contesto per i link". Comunque, grazie per la soluzione, mi ha aiutato molto. – Sam

3

Naturalmente è possibile apportare modifiche nel codice, come suggerito nelle altre risposte. Un'altra alternativa è utilizzare il plug-in Deferred Updates: https://github.com/mbest/knockout-deferred-updates

Il plug-in rimanderà automaticamente eventuali aggiornamenti all'interfaccia utente (o ad eventuali osservabili calcolati) fino a quando non verranno apportate tutte le modifiche nel "thread" corrente.

+1

Questo è ora supportato in modo nativo usando estensori o 'ko.options.deferUpdates = true;' – Johan

7

Questo è probabilmente l'approccio migliore:

function MyVM(){ 
    this.fooObsArray = ko.observableArray([]); 
} 

function Foo(){ 

var self = this; 
self.vm = new MyVM(); 

this.pushSlow = function(arrayToBePushed){ 
    for (int i = 0; i < arrayToBePushed.length; i++){ 
     var element = arrayToBePushed[i]; 
     self.vm.fooObsArray.push(element);   //notifies ui foreach of elements => + delay 
    } 
} 

this.pushFast = function(arrayToBePushed){ 
    var underlyingArray = self.vm.fooObsArray(); 

    for (int i = 0; i < arrayToBePushed.length; i++){ 
     var element = arrayToBePushed[i]; 
     underlyingArray.push(element); 
    } 

    self.vm.fooObsArray.valueHasMutated();   //notifies ui once all elements have been added => - delay 
} 
} 
Problemi correlati