前端内存泄露案例与解决方案

什么是内存泄漏?
内存泄露(Memory Leaks):是指应用程序已经不再需要的内存,由于某种原因未返回给操作系统或者空闲内存池(Pool of Free Memory)。

内存泄露可能带来的问题:变慢、卡顿、高延迟。

内存泄漏的常见示例和防范

1.未能及时清除定时器

// 没去清除的定时器
setTimeout(this.someMethod, 1000)
setInterval(this.someMethod, 1000)
// 正确做法
this.timeout01 = setTimeout(this.someMethod, 1000)
this.interval01 = setInterval(this.someMethod, 1000)
// 在页面销毁的时候,及时清除
beforeDestroy() {
  this.timeout01 && clearTimeout(this.timeout01)
  this.interval01 && clearInterval(this.interval01)
}

2.未能及时取消事件的监听

bus.$on('aaa')
beforeDestroy() {
  // 在页面销毁的时候,及时取消监听
  bus.$off('aaa')
}

3.console.log 没有注释掉或在打包的时候没有清理掉造成泄漏
控制台日志记录对总体内存内置文件的影响,也是个重大的问题。记录错误的对象,可以将大量的数据保留在内存中。传递给console.log的对象是不能被垃圾回收,所以没有去掉console.log可能会存在内存泄漏

4.DOM创建造成内存泄漏

// 元素引用并没有清理
var a = document.getElementById('id');
document.body.removeChild(a);
// 不能回收,因为存在变量a对它的引用。虽然我们用removeChild移除了,但DOM元素还在内存里面。
解决方法: a = null;

5.变量没及时被清理,特别是对于数据量大的变量,要引起重视。
数据量过大:如果在VUE应用中处理了大量的数据,那么会导致内存占用较大。特别是在使用响应式数据时,当数据发生变化时,VUE会对其进行重新渲染,从而占用更多的内存。

methods: {
	fun1() {
		let a = [数据量可能会比较大的数组]
		let b = [数据量可能会比较大的数组]
		let c = [...a, ...b]
		this.fun2(c)
		// 此处应该用完就及时清理掉
		a = null
		b = null
		c = null
	},
	fun2(data) {
		// ......
	}
}

6.如果应用中包含了大量的组件,每个组件都有自己的状态和响应式数据,那么会占用更多的内存。特别是在动态创建和销毁组件时,需要频繁地创建和销毁组件实例,从而导致内存占用较大。
解决办法:组件懒加载-将组件按需加载,只在需要的时候才加载组件,而不是一次性加载所有组件。
以下拿弹窗组件举个例子

// 页面中引入多个弹窗组件
<编辑与新增的组件/>
<拍照的组件/>
<打印的组件/>
// 由于以上组件在页面初始化的时候,是用不到的,点击相应的按钮后才会打开弹窗,这时候最好是加一个v-if判断
<编辑与新增的组件 v-if="isOpen01"/>
<拍照的组件 v-if="isOpen02"/>
<打印的组件  v-if="isOpen03"/>
// 然后对于Element-ui的el-dialog弹窗组件,有个属性要利用起来,关闭时销毁 Dialog 中的元素:destroy-on-close="true"

在这里插入图片描述
7.过多的循环嵌套,或者通过for、forEach等循环处理过于复杂的数据时所定义的变量没及时清理,也会导致内存用量飙升或者内存泄露的问题。平时也要合理使用循环遍历,尽可能减少遍历的次数。

总之,在日常开发的时候,细心点,及时规避会导致内存泄露的代码,就能开发出健康稳健的项目。

  • 6
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值