Skip to content

ECharts 大屏内存泄漏排查与治理

一、问题背景

在可视化大屏项目中,页面通常需要部署到客户现场长期运行,很多场景都是 7 x 24 小时持续展示。

实际项目中遇到过这样的问题:

  • 页面运行几天后出现卡顿
  • 内存占用持续升高
  • 最终浏览器崩溃,导致大屏不可用

如果页面中图表数量较多,并且存在动态刷新需求,就需要重点排查 ECharts 是否引发了内存泄漏问题。


二、常见原因

1. 重复创建图表实例

在动态更新图表时,如果每次都调用 echarts.init() 创建新实例,而不是复用旧实例,就会导致实例不断累积,内存持续增长。

2. 事件监听没有解绑

每个图表都可能绑定点击、悬浮、缩放等事件。如果组件销毁时没有正确调用 off() 解绑,就会残留监听器,导致无法被垃圾回收。

3. 定时器没有清理

很多大屏会使用定时器轮询或定时刷新图表。如果组件卸载时没有及时 clearInterval()clearTimeout(),就可能持续触发更新逻辑,间接造成内存泄漏。


三、真实问题定位

排查后发现,项目中主要问题是:

  • 定时刷新数据时重复执行 echarts.init()
  • 销毁阶段 cleardispose 使用不当
  • 事件解绑和定时器清理不完整

最终导致:

  • 定时器不断触发重绘
  • ECharts 实例越来越多
  • 浏览器内存持续上升,最终崩溃

四、clear()dispose() 的区别

1. clear()

作用:

  • 清空当前图表配置和数据
  • 保留 ECharts 实例本身

适用场景:

  • 需要保留实例,只是重新绘制内容
  • 使用同一个实例反复更新数据

特点:

  • 不会释放实例占用的核心内存
  • 不需要重新 init

2. dispose()

作用:

  • 彻底销毁 ECharts 实例
  • 释放 DOM 引用、事件监听和内部资源

适用场景:

  • 图表生命周期结束
  • DOM 被销毁或组件即将卸载

特点:

  • 会真正释放内存
  • 后续如果还要绘制,需要重新执行 echarts.init()

五、正确治理方案

1. 优先复用实例

推荐在初始化前先判断当前 DOM 上是否已经存在实例:

  • 如果有实例,直接使用 setOption() 更新数据
  • 如果没有实例,再调用 echarts.init()

2. 销毁阶段彻底清理资源

在组件销毁前统一处理:

  • 调用 chart.off() 解绑事件
  • 调用 chart.dispose() 销毁实例
  • 调用 clearInterval()clearTimeout() 清理定时器

3. 避免无意义重绘

在动态更新场景中,尽量:

  • 复用实例
  • 只更新变化的数据
  • 控制刷新频率

六、可以这样向面试官表述

1. 现象

客户现场的大屏运行几天后页面崩溃,本地短时间压测不容易复现。

2. 排查过程

  • 使用 Chrome DevTools 观察内存变化
  • 发现内存随时间持续增长且没有回落
  • 结合代码排查,定位到定时刷新逻辑中重复执行 echarts.init()
  • 同时发现事件监听未解绑、定时器未清理的问题

3. 解决方案

  • 使用 getInstanceByDom() 获取并复用实例
  • 动态更新时统一使用 setOption()
  • 组件销毁时调用 dispose()、解绑事件并清理定时器

4. 结果

  • 大屏长时间运行内存保持稳定
  • 页面卡顿和崩溃问题被解决
  • 项目可以稳定支撑长期在线展示

七、适合写进简历的亮点

简历表达示例:

负责排查并治理 ECharts 大屏内存泄漏问题,定位定时刷新中重复 echarts.init()、事件未解绑、定时器未清理等隐患;通过实例复用、正确销毁和刷新策略优化,保障大屏 7 x 24 小时稳定运行。