Vue Web App 内存泄漏-调试和分析

一、写在前面

js中的内存垃圾回收机制:垃圾回收器会定期扫描内存,当某个内存中的值被引用为零时就会将其回收。当前变量已经使用完毕但依然被引用,导致垃圾回收器无法回收这就造成了内存泄漏。传统页面每次跳转都会释放内存,所以并不是特别明显。

Web App 与 传统Web的区别,因为Web App是单页面应用页面通过路由跳转不会刷新页面,导致内存泄漏不断堆积,导致页面卡顿。

二、泄漏点

  1. DOM/BOM 对象泄漏
  2. script 中存在对DOM/BOM 对象的引用导致
  3. Javascript 对象泄漏
  4. 通常由闭包导致,比如事件处理回调,导致DOM对象和脚本中对象双向引用,这个时常见的泄漏原因

三、代码关注点

  1. DOM中的addEventLisner 函数及派生的事件监听, 比如Jquery 中的on 函数, vue 组件实例的 $on 函数,第三方库中的初始化函数
  2. 其它BOM对象的事件监听, 比如websocket 实例的on 函数
  3. 避免不必要的函数引用
  4. 如果使用render 函数,避免在html标签中绑定DOM/BOM 事件

四、如何处理

  1. 如果在mounted/created 钩子中绑定了DOM/BOM 对象中的事件,需要在beforeDestroy 中做对应解绑处理

  2. 如果在mounted/created 钩子中使用了第三方库初始化,需要在beforeDestroy 中做对应销毁处理

  3. 如果组件中使用了定时器,需要在beforeDestroy 中做对应销毁处理

  4. 模板中不要使用表达式来绑定到特定的处理函数,这个逻辑应该放在处理函数中?

  5. 如果在mounted/created 钩子中使用了 onbeforeDestroy( off)处理

  6. 某些组件在模板中使用 事件绑定可能会出现泄漏,使用$on 替换模板中的绑定

如何在vue 组件中处理addEventListener
created/mounted 生命期钩子函数中定义事件响应函数为对象实例的方法,使用 => 函数来绑定作用域
   调用 addEventListener 添加事件监听
   beforeDestroy 中调用 removeEventListener 移除对应的事件监听,注意前面定义的响应函数方法需要作为第二个参数传入
   然后用 delete 从对象实例移除定义的响应方法,或者将属性设置为 null/undefined
为什么不能使用匿名函数或者已有的函数的绑定来直接作为事件监听函数

这样无法准确移除监听,函数每次绑定返回的是不同的函数实例

具体例子请参考 如下代码

mounted() {
    const box = document.getElementById('time-line')
    this.width = box.offsetWidth
    this.resizefun = () => {
      this.width = box.offsetWidth
    }
    window.addEventListener('resize', this.resizefun)
  },
  beforeDestroy() {
    window.removeEventListener('resize', this.resizefun)
    this.resizefun = null
  }
查找内存泄漏的组件

在组件template 第一个 div 中添加一个 class , 值是和组件同名的CSS 选择器,方便我们快速识别内存泄漏中的组件

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值