问题背景
页面上有多个tab,每个tab下都有一个列表,在多次切换tab后会导致页面白屏崩溃。
排查过程
问题分析
通过chrome devtools的Performance分析切换tab时页面各种情况,开启记录后切换几次tab后得到以下结果
通过上去折线区域可以看到蓝色折线(
JS Heap)一直在上升没有回落的,内存从60MB升到152MB,可以明显看出是存在内存泄漏问题的,同时发现绿色折线(Nodes)也存在同样的情况,说明一直在创建新的节点没有销毁旧的节点,带着这个结论我们用Memory工具分析内存具体情况。
问题定位
通过两次内存快照可以看到内存增长最大的是array对象,其中大部分都是Detached HTMLDivElement,即分离的DOM节点,无法访问但是被某个地方引用着导致垃圾回收机制无法回收其内存,展开其中一个发现该节点是列表中的其中一行数据,并且跟react-dnd代码库相关,猜测可能是该库对拖拽节点的处理有问题。
解决方法
解决办法就是要将列表中的拖拽节点在移除时销毁掉,避免一直存在于内存中,修改代码如下:
// 旧代码
drag(drop(ref));
// 将以上代码改为
useLayoutEffect(() => {
drag(drop(ref));
return () => {
drag(null);
drop(null);
};
}, [drag, drop, ref]);
修改代码后再次用Performance工具得到下图结果:
可以看到内存和节点数量已经不会持续增长而不会回落了!
参考资料: