分析样本

  • 开发环境
  • 项目:百川 2
  • 仪表盘 _ 图表数:小林疋仪表盘测试 _ 3、第一个仪表盘-001 * 5
  • 动作:反复切换 10 次;

分析方式:

仪表盘之间反复切换,使用Performance记录性能火焰图;分析出具体原因之后使用Memory找出具体泄露的代码;

具体步骤

1

根据分析方式的交互,随着反复切换仪表盘,可以看到JS heapListeners直线飙升,可以分析出出现卡顿的原因确实是由于内存泄露导致的,没有在正确的时机销毁\释放掉内存和事件监听;

同样,通过Memory分析发现,在时间轴中能体现出内存占用出现高峰后并没有被释放:

1

挑时间轴中的一个高峰发现能看懂的就这些:

1

就先从这些入手,能看到对象的引用大都在dataSourcechartRefsdashboardDataRefs上:

1

代码修改

主要逻辑是在组件销毁时将引用置为 null,例如:

// BIChartDesigner/CanvasRender.js
useEffect(() => {
  // 这里是点击下钻和查询按钮的收口
  chartDataRef.current.refreshChartData = async ({ drillField }) => {
    resetPagination();
    await requestData({
      isEdit,
      chartDataRef,
      activeComponentId,
      filters,
      panel_id,
      drillField,
      fromScreenShot,
      setLiteLoading,
      global_param_list,
      queryParamsRef,
    });
  };
  return () => {
    chartDataRef.current = null;
  };
}, [chartDataRef, activeComponentId, filters, panel_id, global_param_list]);

同理,在dashboardDataRef.current赋值的位置将其释放;

改完之后看效果:

1

使用相同的分析方式,JS heap从原来的87.5~309减到85.1~237,但是内存还是在增长的趋势,还要继续分析;

Memory可以看到图表相关的数据:

1

盲猜图表可能也发生了内存泄露,并且事件监听最有可能的就是绑定在图表上,我们使用的图表是@visactor/vtable@1.3.1,首先看下 Google 上有没有相关问题搜索,果然,在 github 上就有人提出过 vtable 是有内存释放的问题,并且在issue中也有解答,不过官方在1.3.0这个版本就已经修复了:

1

修复方式:

1

我们的版本使用的是 1.3.1,按道理应该是更新到了,为什么我们的就没办法释放呢,看源码更改的地方是packages/vtable/src/core/BaseTable.ts是不是由于我们使用的是 react 版本没有更新到这个更改呢?于是想到可以在提出这个 bug 的大佬的 codepen 基础上再复现一下,看是不是由于版本的原因:

1

当我看到tableInstance.release()的时候我就感觉离解决不远了,原来图表实例上是有释放的方法的,果然,在我们的代码中,实例化图表之后再销毁时,并没有调用 release 方法,于是在引用了@visactor/vtable组件的地方的useEffect中调用:

useEffect(() => {
  ...
  tempDataRef.current.ins = new ListTable(containerRef.current, options);
  ...
  return () => {
      tempDataRef.current.ins.release();
    }
}, [...])

在重新跑分析方法可以看到,JS heap降到了81.4~162,并且从图中可以分析出内存事件监听和内存都得到了释放:

1

再看看Memory分析:

1

可以看到每次内存高峰上面都有被释放的标记(最后一次是因为还停留在那个页面),通过时间轴对比,可以看出从最初的 110s 完成 10 次切换,速度提高到 55s 完成 10 次切换,速度提高了一倍;

至此,内存泄露的问题得到初步解决,还有对象释放,以及其他图表类型的优化上还有空间;


本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!

koa-compose源码解析笔记 下一篇