2013-09-27 9 views
5

Penso di aver scoperto una perdita di memoria nella libreria trascinabile dell'interfaccia utente jQuery, anche se il problema potrebbe essere causato da Meteor, non ne sono sicuro.Perdita di memoria nell'interfaccia utente jQuery trascinabile con MeteorJS?

Ho notato questo quando la mia app è stata utilizzata per la prima volta da un gruppo di utenti tutto il giorno. Ho avuto l'app aperta in una scheda e alla fine della giornata era così lento che era inutilizzabile. Ho controllato l'utilizzo della memoria e ho notato che utilizzava quasi un intero GB di memoria.

Per ricreare questo problema, ho scritto uno script PhantomJS che accede all'app e fa un mucchio di aggiornamenti mentre registra l'utilizzo della memoria negli strumenti di sviluppo di Chrome. Così sono andato a cercare il codice che stava causando il problema, ho scoperto che erano gli eventi trascinabili/trascinabili che stavo mettendo sugli elementi nell'evento di rendering del mio modello.

Ecco un esempio di utilizzo della memoria, mentre il mio script fantasma corre con trascinabili: enter image description here

ed ecco il mio utilizzo della memoria senza trascinabili: enter image description here

NOTA: ho provato trascinabili & droppable insieme, come anche separatamente, con le opzioni di configurazione ZERO e non ha trovato cambiamenti evidenti nella perdita.

Come si può notare dal primo grafico, l'utilizzo della memoria non viene rilasciato dopo l'interruzione dello script (circa 1,4 minuti) e l'utilizzo della memoria è notevolmente migliorato (da 14,3 MB a 169 MB). Si tratta di circa 300-500 aggiornamenti (qualcosa che probabilmente non è del tutto irrealistico, soprattutto nel corso di un'intera giornata con molti utenti).

Penso che la chiave qui sia il numero di nodi che Chrome ti dà nella scheda Timeline. Dopo che lo script è stato eseguito ci sono 100.000 domini DOM in base al numero di nodi DOM, nel secondo ce ne sono circa 1000.

Ho creato un progetto completamente indipendente per garantire che questo problema fosse reale. Ho messo questo su Github per chiunque con cui giocare. Il mio script phantomJS si trova nella directory principale.

https://github.com/davidworkman9/jQueryDraggableMemLeakWithMeteor

io sono sicuro di dove andare da qui, se Meteor o jQuery UI, o se il problema è risolvibile senza un punto da uno di questi pacchetti.

+0

Può non essere correlato, ma mi ricorda di http://point.davidglasser.net/2013/06/27/surprising-javascript-memory-leak.html –

+0

Ho visto anche quello, quella fuga sembra essere correlata alle chiusure dove come quello che sta succedendo qui (penso) è che i nodi DOM non vengono ripuliti quando il modello rielabora. – Dave

risposta

0

Per chi soffre di questo problema, ho progettato una correzione temporanea (che viene eseguita per ogni re-rendering del modello).

(function() { 
    var oldRender = Spark.renderToRange; 
    Spark.renderToRange = function (range, htmlFunc) { 
     var oldFunc = htmlFunc; 
     htmlFunc = function() { 

      // put in clean up code here Example: 
      if(range._start === $('#myTemplate')[0]) { 
       $('#myTemplate').find('.ui-draggable').draggable('destroy'); 
      } 
      // end clean up code 

      return oldFunc.apply(this, arguments); 
     }; 
     return oldRender.apply(this, arguments); 
    }; 
})(); 

Uno degli sviluppatori Meteor fondamentali di questo forum di Google Gruppi me (link) ha informato che sono ri-scrittura del pacchetto di template e questo sarà risolvere questo problema.