I have an application that allows a user to view details on a specific case w/out a postback. Each time a user requests data from the server I pull down the following markup.
<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>
Next I take the above and innerHTML it to a new DOM element like so:
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);
but after the above, I use some jQuery to remove the nasty aspnet junk
$('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);
My question is this - When using IESieve I notice no actual leaks but an ever growing number of DOM elements (thus memory usage).
What can I improve on in the client-side to actually cleanup this mess? Note- both IE7/8 show these results.
EDIT: I did finally get this working and decided to write a short blog post with complete source code.
remove()
and its ilk only remove elements from the DOM. They still exist in memory somewhere.This is a known problem with AJAX and Web 2.0. There's little you can do aside from designing your site to ensuring that you occasionally have a page refresh to wipe things away.
I think the "always growing memory consumption" is somewhat misunderstood. It has to do with memory management inside the browser (and also on Windows in general) more than it has to do with your JS code. Memory managers typically keep allocating (or avoid releasing) until they have to. On systems based on pagefiles and memory mapping, allocating and releasing memory is very time consuming.
So even if your nodes are released from the actual document structure and DOM - there is hardly any way to measure it from Windows itself in "realtime".
Try this:
Start Taskmanager, switch to process tab and watch memory of your browser
Load in a HTML document that allocates 100.000 nodes, watch the memory consumption grow
Click a button in the page that releases all the nodes. Notice that little happens in terms of memory release.
Now minimize the browser-window, and maximize it again. In 90% of all cases the browser now dumps the memory if doesnt use and you will see how much it really consumes.
You can have a browser consume 500 megabytes of ram (not above mentioned example), but when you minimize and maximize it, it releases everything and suddenly it only uses 50 megabytes.
The tricky part is figuring out where a reference still exists to the offending nodes.
You're doing this the hard way — you're adding all the markup to the page, then removing the stuff you don't want. I'd do it this way instead:
This isn't guaranteed to stop the leak, but it's a good start.
Source