react-dnd内存泄漏问题排查

872 阅读2分钟

问题背景

页面上有多个tab,每个tab下都有一个列表,在多次切换tab后会导致页面白屏崩溃。

排查过程

问题分析

通过chrome devtoolsPerformance分析切换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工具得到下图结果: 可以看到内存和节点数量已经不会持续增长而不会回落了!

参考资料: