2012-12-28 22 views
8

Ho il seguente codiceangolare JS ng-repeat consuma più memoria del browser

<table> 
<thead><td>Id</td><td>Name</td><td>Ratings</td></thead> 
<tbody> 
    <tr ng-repeat="user in users"> 
    <td>{{user.id}}</td> 
    <td>{{user.name}}</td> 
    <td><div ng-repeat="item in items">{{item.rating}}</div></td> 
    </tr> 
</tbody> 
</table> 

utenti è un array di oggetti utente con solo id e il nome. numero di oggetti utente nell'array - 150

elementi è un array di oggetti con solo ID e valutazione. numero di oggetti oggetto nell'array - 150

Quando eseguo il rendering nel browser, sono necessari circa 250 MB di memoria heap quando ho provato la creazione di profili nel mio chrome - v23.0.1271.95.

Sto usando AngularJS v1.0.3.

C'è un problema con l'angolare o sto facendo qualcosa di sbagliato qui?

Ecco il violino JS

http://jsfiddle.net/JSWorld/WqSGR/5/

risposta

12

Beh, non è la ripetizione ng di per sé. Penso che sia il fatto che stai aggiungendo i binding con {{item.rating}}.

Tutti quegli attacchi registrano orologi sulla portata così:

  • 150 * 2 = 300 (per le info 2 utenti)
  • 150 * 150 = 22500 (per le info valutazione)
  • totali di 22800 funzioni di orologio + 22800 elementi dom.

Questo avrebbe spinto la memoria per un valore di 250 MB concepibile

Da Databinding in angularjs

Non si può mostrare in realtà più di circa 2.000 pezzi di informazioni per un umana su una singola pagina. Qualunque cosa in più è un'interfaccia utente davvero brutta, e gli umani non possono elaborarlo comunque.

+0

Grazie Liviu! Ho provato a scrivere una direttiva personalizzata per la ng-repeat interna. Ciò ha effettivamente ridotto la memoria a molto meno (circa 40 MB). Ecco il JS Fiddle dello stesso: http://jsfiddle.net/JSWorld/WqSGR/9/ –

+0

Qual è il vero caso d'uso che stai cercando di ottenere? –

+0

Per ogni utente, voglio elencare la valutazione che ha dato per ogni articolo disponibile nell'ordine decrescente di valutazione. –

0

voglio dire la perdita è nella seconda serie, perché si sta potenzialmente loop attraverso la stessa matrice e la visualizzazione di ogni elemento per ogni riga utente in modo che gli utenti a seconda su quanto sono grandi i dati del test, quella vista potrebbe diventare piuttosto grande. Potrei fare un po 'di più investigando. il tuo violino è qualcosa di completamente diverso.

+0

Ho aggiornato il violino. Spiacente, ho postato il link sbagliato. Ancora il problema persiste per me nel mio caso. Perché il ciclo continuo costa così tanta memoria. C'è generalmente un problema con l'uso di ng-ripetizioni annidate? –

0

In questo momento si esegue il ciclo di 150 X 150 = 22500 elementi. E registrando un orologio (o attraverso una direttiva aggiungendo solo la valutazione dell'oggetto) a ciascuno di essi.

- considerare l'aggiunta della valutazione dell'utente all'oggetto utente stesso. Aumenterà la dimensione di ciascun oggetto utente, ma si collegheranno solo 150 elementi e si registreranno solo gli orologi.

Inoltre, prendere in considerazione lo Indexes. È evidente che potrebbero esserci utenti o valutazioni di articoli simili. Basta indicizzarli, quindi anziché ricorrere a oggetti pesanti, puoi ridurli.

Una cosa di più - se si sta andando ad essere in esecuzione della direttiva stessa istanza, almeno modificare il codice:

var text = myTemplate.replace("{{rating}}",myItem.rating); 

ad un calcolo concat stringa di stile:

var text = '<div>' + myItem.rating + '</div>'; 

Questa volontà risparmia un pezzo ENORME al momento del calcolo. Ho fatto uno JSperf per questo caso, notare la differenza, è circa il 99% più veloce ;-)

Problemi correlati