如何使用Chrome控制台查看DOM泄漏

2018年03月03日Web前端

用上了高大上Angular框架,但是发现了好几个因DOM节点未释放照成的内存泄漏问题。

我们都知道被移到内存中的DOM元素因为有JS的引用所以无法被GC回收,但是由于他们不在DOM树上,所以,他们的parentNode肯定是null了。借助于chrome控制台下的Memory工具下的内存快照(take heap snapshot),我们可以很详细地找到我们需要的信息。

一、制造DOM泄漏

<body>
    <button id="create">泄漏</button>
</body>
var oDiv = null;
function create() {
    oDiv = document.createElement('div');
    var oSpan = document.createElement('span');
    oDiv.appendChild(oSpan);
}

document.getElementById('create').addEventListener('click', create);

我们手动制造DOM泄漏,来看下如何查寻找泄漏的DOM元素。

二、定位

直接点击按钮,触发create函数。打开控制台工具,进入Memory下。

选中Take heap snapshot,该功能可以查看当前使用内存的快照,再点击Take snapshot。出现了个Snapshot1。

此时,我们在Summary右侧中的输入框中输入detached DOM tree,就可以看到分离的DOM节点了。

  • Distance表示对象到根的引用层级距离。
  • Objects Count表示当前有多少个该类的对象。
  • Shallow Size表示对象所占内存(不包含内部引用的其它对象所占的内存)(单位:字节)。
  • Retained Size表示对象所占总内存(包含内部引用的其它对象所占的内存)(单位:字节)。

或者,我们可以直接切换到Containment下,也有个Detached DOM trees。

点开Detached DOM trees,查看详细的DOM树,

黄色背景的节点表示有JS直接引用,而红色背景节点表示JS间接引用(可能是黄色节点的子节点)。这些都是因为引用关系造成DOM树节点未释放的。 我们只要保证黄色节点在他的使用时间范围内存在就可以了。优先处理黄色节点,也可以缩减红色节点的数量。

三、快速定位

其实我们可以手动的快速对比两次shapshot的中的DOM树的变化。当然工具提供了更为简单的方式。 在我们需要统计的范围之间,抓两次或多次内存快照,然后进行对比,

直接进入comparison,右侧的下拉可以选择你对比的是那个snapshot。在输入框中再次输入detached dom tree。

可以对比看到此次多了个分离的div元素。

右侧New数量表示两个快照期间新增了多少个,而详细中的实心点表示他是新增加的,Deleted表示的是删除。而Delta表示最后的详细情况,+1表示新增了一个,如果本次操作本不会增加DOM的话,那么久该查下是否有DOM泄漏了。