我有一个应用程序,允许用户在回发后查看特定案例的详细信息。每次用户从服务器请求数据时,我都会下拉以下标记。
<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>
接下来我将上面的内部HTML和它带到一个新的DOM元素,如下所示:
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);
但是在上面之后,我使用一些jQuery来删除令人讨厌的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);
我的问题是 - 当使用IESieve时,我注意到没有实际的泄漏,但是DOM元素的数量不断增加(因此内存使用量)。
在客户端我可以改进哪些实际清理这个烂摊子?注意 - IE7 / 8都显示了这些结果。
编辑:我最终完成了这项工作,并决定编写一份包含完整源代码的简短blog post。
答案 0 :(得分:12)
棘手的部分是找出有问题的节点仍存在参考的位置。
你这样做很难 - 你将所有标记添加到页面,然后删除你不想要的东西。我会这样做:
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;
这不能保证能够阻止泄漏,但这是一个良好的开端。
答案 1 :(得分:7)
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 = '';
}
答案 2 :(得分:2)
remove()
及其同类只删除DOM中的元素。它们仍然存在于某个地方的记忆中。
这是AJAX和Web 2.0的已知问题。除了设计您的网站以确保您偶尔刷新页面以消除内容之外,您几乎无能为力。
答案 3 :(得分:1)
我认为“不断增长的内存消耗”有些被误解了。它与浏览器内部的内存管理(以及一般的Windows)有关,而不是与JS代码有关。内存管理员通常会继续分配(或避免释放),直到他们不得不这样做。在基于页面文件和内存映射的系统上,分配和释放内存非常耗时。
因此,即使您的节点从实际文档结构和DOM中释放 - 几乎没有任何方法可以“实时”从Windows本身进行测量。
试试这个:
启动Taskmanager,切换到进程选项卡并观察浏览器的内存
加载分配100.000个节点的HTML文档,观察内存消耗增长
单击页面中释放所有节点的按钮。请注意,在内存释放方面几乎没有发生。
现在最小化浏览器窗口,并再次最大化它。在90%的情况下,如果不使用,浏览器现在会转储内存,你会看到它真正消耗了多少。
你可以让浏览器消耗500兆字节的ram(不是上面提到的例子),但是当你最小化并最大化它时,它会释放所有内容,突然它只使用50兆字节。