【问题标题】:jQuery order elements, remove, detach, clone, append memory leaksjQuery order 元素,remove,detach,clone,append 内存泄漏
【发布时间】:2012-02-20 14:14:18
【问题描述】:

我有一个父 div,其中包含大约 300 个 div,所有这些都包含图像和一些文本。我有一个数组,其中包含我需要重新排序 div 的所有信息,使用引用..

if if then 在我订购后循环遍历数组,然后相应地移动元素,我会得到高达 100MB 额外时间的严重内存泄漏,我对它们进行排序!

我尝试了一些方法,但仍然没有成功

$.each(gameArray , function($idx, $itm) { 
    $("#elementid"+ $itm.split('|#|')[0] ).appendTo($("#parent"));
}); 

又一次尝试

$.each(gameArray , function($idx, $itm) { 
    var element = $("#elementid"+ $itm.split('|#|')[0] ).detach();
    element.appendTo($("#parent"));
    element = null;
}); 

又一次尝试

$.each(gameArray , function($idx, $itm) { 
    var element = $("#elementid"+ $itm.split('|#|')[0] ).clone(true).remove();
    element.appendTo($("#parent"));
    element = null;
}); 

我读到 detach 将元素保留在 DOM 中,因此当您将其放回页面时,它不会重新创建任何内容,也不会增加内存,但它似乎不起作用?!

我有什么遗漏吗?必须有一种在不增加内存的情况下对它们进行排序的方法吗?

我发现的所有示例都使用了包含大约 10 个列表元素的有序列表,因此您不会注意到内存增加!

【问题讨论】:

  • 您是否尝试过在不使用 jQuery 的情况下移动 dom 元素?也许不断创建 jquery 对象是个问题?!
  • 还没有!我现在看看并发布我的发现!
  • var parent = document.getElementById('game_panel'); $.each(koko.data('newGameArray'), function($idx, $itm) { var element = document.getElementById('gameidis'+$itm.split('|#|')[0]); 父.appendChild(element.parentNode.removeChild(element)); });使用标准 javascript 会导致同样的泄漏!
  • @RoryPickering 这仍然不是标准的 JavaScript。 $.each(..) 也是一个jQuery方法。
  • @RobW 哦耶!!!看起来好像只是对 div 的操作导致了韭菜!我正要尝试 dgilland 下面发布的方法!

标签: javascript jquery memory-management memory-leaks


【解决方案1】:

在遇到性能问题的繁重 (DOM) 操作中,您应该完全放弃 jQuery,并返回到原生 JavaScript(尤其是如果非 jQuery 替代方案适用于所有现代浏览器)。

var fragment = document.createDocumentFragment(); // Temporary storage
for (var $idx=0, len = gameArray.length; $idx<len; $idx++) {
    var $itm = $gameArray[$idx];
    fragment.appendChild(
        document.getElementById("elementid" + $itm.split('|#|', 1)[0] )
    );
}
// Append all items to parent
document.getElementById('parent').appendChild(fragment);

使用的方法有:

【讨论】:

  • 感谢您的回复,但我在这个例子中仍然存在内存泄漏......如果我删除实际将元素存储在片段中的代码并附加它,它不会泄漏内存,所以它是 deifnalty 不是任何其他代码!奇怪!
  • 是的,我明白了,刚刚做了一个快速测试,它似乎是图像,如果我从每个 div 中去掉 img 标签,内存使用量不会增加!每个图像只有大约 100 x 75 但没有它们在内存中保持不变!也许你不能在碎片化的内存中存储一​​个 img?!
  • >_> DOM 没有任何问题。图像被加载到内存中。
  • 如果我在 div 中有图像,当我重新排序时,firefox 的内存使用量会上升,如果我在 div 中没有图像,内存使用量保持不变。使用您在上面发布的方法
  • 抱歉 Rob,不是图片。它被隐藏了 iFrame!
【解决方案2】:

试试这个例子:

HTML:

<div id="parent">
    <div id="0">0</div>
    <div id="1">1</div>
    <div id="2">2</div>
    <div id="3">3</div>
    <div id="4">4</div>
    <div id="5">5</div>
    <div id="6">6</div>
    <div id="7">7</div>
    <div id="8">8</div>
    <div id="9">9</div>
</div>

Javascript:

var games = [ 4, 3, 0, 2, 5, 1, 6, 9, 7, 8 ]; // desired sort order

var $parent = $('#parent');
var $children = $parent.children('div');

$children.detach().sort(function(a,b){
    var aId = parseInt( $(a).attr('id'), 10 );
    var bId = parseInt( $(b).attr('id'), 10 )
    return games.indexOf(aId) > games.indexOf(bId);
});

$parent.append($children);

这会分离您的子级,对其进行排序,然后将它们附加回父级,从而避免在排序过程中修改 DOM。

【讨论】:

  • 我似乎仍然使用这种方法得到相同的内存泄漏!?
猜你喜欢
  • 1970-01-01
  • 2010-12-02
  • 2011-05-09
  • 1970-01-01
  • 2013-04-10
  • 2011-09-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多