【发布时间】:2013-09-05 16:40:13
【问题描述】:
背景:受 this question 和 this question 关于 D3 内存使用的启发,我决定深入研究它的实际工作原理,并很快找到了 cautions about repeated add/remove of DOM nodes in IE。
为了与 D3 所做的其他事情隔离开来,我首先尝试了每秒添加/删除 1000 个圆圈的基本 SVG 案例:
var count = 1000;
var svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
svg.setAttribute('width', '800');
svg.setAttribute('height', '800');
document.body.appendChild(svg);
function update() {
// remove existing circles
var circles = svg.querySelectorAll("circle")
for (var i = circles.length - 1; i >= 0; i--) {
var parent = circles[i].parentNode;
if (parent) parent.removeChild(circles[i]);
};
// add new ones. Yes, would make more sense to update the x,y on the existing
// circles but this is to show what happens in IE with lots of nodes being added/removed
for (var j = count - 1; j >= 0; j--) {
var node = document.createElementNS("http://www.w3.org/2000/svg", 'circle');
node.id = 'id' + Math.random();
node.setAttributeNS(null, "cx", Math.random()*800);
node.setAttributeNS(null, "cy", Math.random()*800);
node.setAttributeNS(null, "r", 5);
node.setAttributeNS(null, "fill", "blue");
svg.appendChild(node);
};
}
setInterval(update, 1000);
我发现这会在 IE9 和 IE10 中缓慢泄漏内存。现场版见这里:http://bl.ocks.org/explunit/6413259
我可以做些什么(如果有的话)来防止泄漏,这对如何编写针对 IE 的 D3 代码添加/删除大量节点有什么影响?
其他说明:
受this article 的启发,我尝试了一种简单的节点池方法,将移除的节点推入堆栈:
if (parent) circlePool.push( parent.removeChild(circles[i]) );
并在以后重复使用它们:
var node;
if (circlePool.length == 0) {
node = document.createElementNS("http://www.w3.org/2000/svg", 'circle');
} else {
node = circlePool.pop();
//TODO: clear out attributes of the node
}
但这并没有什么区别。
【问题讨论】:
标签: javascript internet-explorer memory-leaks svg d3.js