一个后台管理系统,用户反馈「开久了越来越卡,最后崩掉」。打开 Chrome 任务管理器,发现标签页内存从 200MB 一路涨到 2GB。
排查步骤
- DevTools → Memory → 拍快照
- 操作一段时间(切换路由、打开弹窗)
- 再拍快照,选 Comparison,看新增对象
- 发现大量 Detached DOM tree 和 Timer
定位到问题
有个实时刷新的组件,在 mounted 里 setInterval,但 beforeDestroy 里忘了 clearInterval。路由切走后组件销毁,定时器还在跑,回调里引用了组件实例和 DOM,导致整棵 DOM 树无法回收。
// 问题代码
mounted() {
this.timer = setInterval(() => {
this.fetchData(); // 引用 this,组件无法回收
}, 5000);
}
// 修复
beforeDestroy() {
clearInterval(this.timer);
this.timer = null;
}
其他常见泄漏源
- addEventListener 没 remove
- 全局事件总线 on 了没 off
- 未取消的 fetch / axios 请求,回调里 setState
- 闭包引用了大对象
- Vuex / Pinia 里存了组件实例
- 第三方图表库(ECharts)实例没 dispose
预防
写组件时养成习惯:mounted 里注册了什么,beforeDestroy 里就反注册什么。ECharts 用 dispose(),WebSocket 用 close()。可以写一个 mixin 统一管理。

Comments 3 条评论
定时器没清我也踩过,一模一样
Detached DOM 那个对比快照很好用
ECharts 忘了 dispose 也会漏