前端内存泄漏及解决方案

573 阅读2分钟

背景

页面出现卡死现象,点击无反应。

发现问题

打开任务管理器,看到内存占有率很高,初步判断可能存在内存泄漏的情况。 当内存占用越来越高,会影响系统性能,甚至进程崩溃。

  • 首先开启浏览器的无痕模式,检查网页程序代码
  • 找到Performance面板,用来监控性能指标的

引起内存泄漏的原因

  • 意外的全局变量 由于JS对未声明变量的处理方式是在全局对象上创建该变量的引用。在浏览器中,全局对象就是window对象。变量在窗口关闭或重新刷新页面之前都不会释放,如果未声明的变量缓存大量的数据,就会导致内存泄漏 解决方法:
    • 避免创建全局变量
    • 使用严格模式,在JS文件头部或函数的顶部加上use strict
  • 闭包引起的内存泄漏 原因:闭包可以读取函数内部的变量,让这些变量始终保存在内存中。如果在使用结束后没有将局部变量清除,就会导致内存泄漏。

解决方法: 将事件处理函数定义在外部,解除闭包。或在定义事件处理函数的外部函数中。

  • 没有清理的DOM元素引用 解决方法:手动删除,element.btn = null

  • 被遗忘的定时器或回调 解决方法:

    • 手动删除定时器和DOM
    • removeEventListener移除事件监听

vue中容易出现内存泄漏的情况

  • 全局变量造成的内存泄漏 声明的全局变量在切换页面的时候没有清空 解决方法:在页面卸载的时候顺便处理掉该引用
  • 监听在window/body等事件没有黑帮 特别注意window.addEventListener之类的时间监听 解决方法:在页面销毁时,解除引用,释放内存
  • v-if指令会产生内存泄漏 v-if绑定到false的值,实际上dom元素在隐藏的时候没有被真实的释放掉。 解决方法:使用选项API中的destroy()方法将其清除

ES6防止内存泄漏

ES6推出两种新的数据结构:weakset和weakmap。他们对值的引用都是不计入垃圾回收机制的