Vue 中导致 detached 元素产生的常见行为

Vue 中导致 detached 元素产生的常见行为

在 Vue 应用中,detached 元素指的是已经从 DOM 树中移除但仍然被 JavaScript 引用着的 DOM 节点。这些元素会导致内存泄漏,因为它们占用的内存无法被垃圾回收机制回收。以下是 Vue 中常见会导致 detached 元素产生的行为:

1. 未正确清理的全局事件监听器

javascript 复制代码
mounted() {
  window.addEventListener('resize', this.handleResize)
},
beforeDestroy() {
  // 如果忘记移除监听器,相关元素可能保持引用
  // window.removeEventListener('resize', this.handleResize)
}

2. 第三方库未正确销毁

javascript 复制代码
mounted() {
  this.chart = new Chart(this.$refs.canvas, {...})
},
beforeDestroy() {
  // 如果忘记调用销毁方法
  // this.chart.destroy()
}

3. 未清理的定时器

javascript 复制代码
data() {
  return {
    timer: null
  }
},
mounted() {
  this.timer = setInterval(() => {
    // 一些操作
  }, 1000)
},
beforeDestroy() {
  // 如果忘记清除定时器
  // clearInterval(this.timer)
}

4. 未清理的 Vue 自定义事件

javascript 复制代码
mounted() {
  this.$on('custom-event', this.handleEvent)
},
beforeDestroy() {
  // 如果忘记移除事件监听
  // this.$off('custom-event', this.handleEvent)
}

5. 在组件销毁后仍然持有 DOM 引用

javascript 复制代码
data() {
  return {
    elements: []
  }
},
methods: {
  cacheElement() {
    this.elements.push(document.getElementById('some-element'))
  }
}
// 如果 elements 数组不清空,引用的 DOM 元素会保持
// 这时候包含some-element元素的组件被销毁,DOM的引用依然存在

6. 使用 v-if 切换组件时的引用保留

javascript 复制代码
// 父组件
<template>
  <child-component v-if="showChild" ref="child"/>
</template>

// 如果在其他地方保持了对 this.$refs.child 的引用
// 即使child-component组件被销毁,引用仍然存在
mounted() {
  this.detachedElement = this.$refs.child;
}

如何检测

方式一

  1. 使用 Chrome DevTools 的 Memory 工具
  2. 先手动触发垃圾回收
  3. 拍摄堆快照(Heap snapshot)
  4. 搜索 "detached" 来查找分离的 DOM 树

方式二

  1. 使用 Chrome DevTools 的 Memory 工具
  2. 先手动触发垃圾回收
  3. 拍摄分离的元素(Detached elements)

拍摄分离的元素可能导致原本被回收的 elements 没有被回收,所以多次拍摄会产生影响,关闭 DevTools 或刷新页面后引用会释放。拍摄堆快照无此问题。

相关推荐
GISer_Jing22 分钟前
前端面试通关:Cesium+Three+React优化+TypeScript实战+ECharts性能方案
前端·react.js·面试
落霞的思绪1 小时前
CSS复习
前端·css
咖啡の猫3 小时前
Shell脚本-for循环应用案例
前端·chrome
百万蹄蹄向前冲6 小时前
Trae分析Phaser.js游戏《洋葱头捡星星》
前端·游戏开发·trae
朝阳5816 小时前
在浏览器端使用 xml2js 遇到的报错及解决方法
前端
GIS之路6 小时前
GeoTools 读取影像元数据
前端
ssshooter7 小时前
VSCode 自带的 TS 版本可能跟项目TS 版本不一样
前端·面试·typescript
Jerry7 小时前
Jetpack Compose 中的状态
前端
dae bal8 小时前
关于RSA和AES加密
前端·vue.js
柳杉8 小时前
使用three.js搭建3d隧道监测-2
前端·javascript·数据可视化