2009-04-20 4 views
27

J'ai une application qui permet à un utilisateur de visualiser des détails sur un cas particulier w/un postback. Chaque fois qu'un utilisateur demande des données au serveur, je décroche le balisage suivant.Comment disposer des éléments DOM en JavaScript pour éviter les fuites mémoire

<form name="frmAJAX" method="post" action="Default.aspx?id=123456" id="frmAJAX"> 
<div> 
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" /> 
</div> 
<div> 
<input type="hidden" name="__EVENTVALIDATION" id="__EVENTVALIDATION" /> 
</div> 
<div id="inner"> 
<!-- valid info here --!> 
</div> 
</form> 

Ensuite je prends ce qui précède et innerHtml à un nouvel élément DOM comme ceci:

success: function(xhtml) { 
     var tr = document.createElement('tr'); 
     var td = document.createElement('td'); 
     var container = document.createElement('div'); 

     obj.parentNode.parentNode.parentNode.insertBefore(tr, obj.parentNode.parentNode.nextSibling); 

     td.appendChild(container); 
     container.innerHTML = xhtml; 
     tr.appendChild(td); 

mais après ce qui précède, j'utiliser une jQuery pour enlever la malbouffe méchant aspnet

$('form:eq(1)').children().each(
    function() { 
     if ($('form:eq(1)').find('div').filter(function() { return $(this).attr('id') == ''; }).remove()); 
    } 
); 

//Capture the remaining children 
var children = $('form:eq(1)').children(); 

// Remove the form 
$('form:eq(1)').remove(); 

// append the correct child element back to the DOM 
parentObj.append(children); 

Ma question est - Lorsque vous utilisez IESieve Je remarque pas de fuite réelle, mais un nombre toujours croissant d'éléments DOM (donc l'utilisation de la mémoire).

Que puis-je améliorer sur le côté client pour nettoyer ce désordre? Remarque- les deux IE7/8 montrent ces résultats.

EDIT: J'ai finalement obtenu ce travail et j'ai décidé d'écrire un court blog post avec le code source complet.

+0

Vous devriez vraiment accepter une réponse à cette question maintenant .... – Blazemonger

+0

Pouvez-vous mettre à jour l'URL de blog post? – Christian

+1

@ Christian juste fait (désolé pour le lien brisé) –

Répondre

12

La partie difficile est de déterminer où une référence existe toujours pour les nœuds incriminés.

Vous faites ceci à la dure - vous ajoutez tout le balisage à la page, puis enlevez les choses que vous ne voulez pas. Je ferais de cette façon à la place:

var div = document.createElement('div'); 
// (Don't append it to the document.) 

$(div).html(xhtml); 

var stuffToKeep = $(div).find("form:eq(1)> *").filter(
    function() { 
    return $(this).attr('id') !== ''; 
    } 
); 

parentObj.append(stuffToKeep); 

// Then null out the original reference to the DIV to be safe. 
div = null; 

Ceci n'est pas garanti pour arrêter la fuite, mais c'est un bon début.

+0

C'est un grand pas en avant car la plupart des éléments DOM qui traînent sont ceux que je supprimais et que je n'utilisais jamais. Je vous remercie! –

2

remove() et ses éléments suppriment uniquement les éléments du DOM. Ils existent toujours dans la mémoire quelque part.

Ceci est un problème connu avec AJAX et Web 2.0. Il y a peu de choses que vous pouvez faire en dehors de la conception de votre site pour vous assurer de temps en temps une actualisation de page pour effacer les choses.

+3

Vous ne pouvez pas les disposer de telle sorte que lorsque le garbage collector javascript vient autour, ceux-ci les éléments sont supprimés de la mémoire? –

+0

On supposerait que ce soit le cas, mais apparemment ce n'est pas le cas. – Randolpho

+2

Hmm ... après quelques recherches, vous pourriez essayer certaines des solutions discutées sur cette page: http://social.msdn.microsoft.com/Forums/en-US/iewebdevelopment/thread/c76967f0-dcf8-47d0-8984 -8fe1282a94f5 – Randolpho

1

Je pense que la « consommation de mémoire toujours en croissance » est un peu mal compris. Cela a à voir avec la gestion de la mémoire dans le navigateur (et aussi sur Windows en général) plus qu'avec votre code JS. Les gestionnaires de mémoire continuent généralement d'allouer (ou d'éviter de libérer) jusqu'à ce qu'ils le fassent. Sur les systèmes basés sur des fichiers de page et le mappage de la mémoire, l'allocation et la libération de la mémoire prennent beaucoup de temps. Par conséquent, même si vos nœuds sont libérés de la structure du document et du DOM, il n'y a pratiquement aucun moyen de le mesurer à partir de Windows lui-même en "temps réel".

Essayez ceci:

  1. Démarrer Taskmanager, commutateur pour traiter onglet et regarder la mémoire de votre navigateur

  2. charge dans un document HTML qui alloue 100.000 nœuds, regarder la consommation de mémoire croître

  3. Cliquez sur un bouton dans la page qui libère tous les nœuds. Notez que peu de choses se passent en termes de libération de la mémoire.

  4. Maintenant, réduisez la fenêtre du navigateur et optimisez-la à nouveau.Dans 90% des cas, le navigateur déverse la mémoire s'il ne l'utilise pas et vous verrez combien il consomme vraiment.

Vous pouvez avoir un navigateur consomme 500 Mo de RAM (non indiqué ci-dessus par exemple), mais quand vous réduisez au minimum et à maximiser, il libère tout et tout d'un coup, il utilise seulement 50 méga-octets.

6
function discardElement(element) { 
    var garbageBin = document.getElementById('IELeakGarbageBin'); 
    if (!garbageBin) { 
     garbageBin = document.createElement('DIV'); 
     garbageBin.id = 'IELeakGarbageBin'; 
     garbageBin.style.display = 'none'; 
     document.body.appendChild(garbageBin); 
    } 
    // move the element to the garbage bin 
    garbageBin.appendChild(element); 
    garbageBin.innerHTML = ''; 
} 

Source

+0

Je sais qu'il est un peu en retard dans le jeu ... –

+2

Un tel bel exemple de pourquoi IE suce ... –

+2

vous ne donnez aucune explication quant à pourquoi cela fonctionnerait même. cela n'a aucun sens. – vsync

Questions connexes