「这是我参与11月更文挑战的第12天,活动详情查看:2021最后一次更文挑战」
内存问题的外在表现
-
页面出现延迟加载或经常性暂停(网络环境正常的)
任务:如何使用Performance进行观察?
-
页面持续性出现糟糕的性能
内存膨胀:页面为了使用的流畅,去申请一段非常大的内存空间,空间超出当前的负载
-
页面性能随时间延长越来越差 内存溢出的情况,刚刚开始内存泄漏还没有出现堆叠的情况,内存就保留有较多的空间,用户就不会体验到明显的卡顿,在内存泄漏堆叠情况严重造成内存溢出之后,就会出现明显的卡顿
监控内存
我们常见的内存出现问题有三种情况:
- 内存泄漏
- 内存膨胀
- 频繁的垃圾回收
界定内存问题的标准
- 内存泄漏: 内存使用持续升高
- 内存膨胀:在多数设备上都存在性能问题
- 频繁垃圾回收:通过内存变化图进行分析
监控内存的几种方式
- 浏览器任务管理器
- Timeline 时序图记录
- 堆快照查找分离DOM
- 判断是否存在频繁的垃圾回收
浏览器任务管理器
我们就先创建一个html文件进行浏览器的性能试验
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>任务管理器监控内存变化</title>
</head>
<body>
<button id="btn">ADD</button>
<script type="text/javascript">
const btn = document.getElementById("btn");
btn.onclick = function() {
let arr = new Array(100000);
}
</script>
</body>
</html>
然后打开该html文件,通过快捷键Shift+Esc按钮调出浏览器任务管理器
选中任意一个右键-> 选中 JavaScript使用的内存
那我们如何查看内存使用呢?
首先我们会发现有两个内存:
- 内存占用空间 -> DOM节点占用的内存,如果内存不断加大,就是不断在新增DOM节点
- JavaScript使用的内存: 所有可达对象的使用内存,如果值在不断加大,就是说明我们当前在不断新增对象,或者是可达对象的值不断在增长
ok明白这些之后我们开始测试:
点击add按钮
我们会发现使用内存明显增加了许多,确实是有监听到内存的使用的。
Timeline 时序图记录
老规矩上测试用例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>任务管理器监控内存变化</title>
</head>
<body>
<button id="btn">ADD</button>
<script type="text/javascript">
const arrList = []
function test() {
for(let i = 0; i< 100000; i++){
document.body.appendChild(document.createElement('p'))
}
arrList.push(new Array(100000).join('x'))
}
const btn = document.getElementById("btn");
btn.addEventListener('click', test)
</script>
</body>
</html>
打卡页面后进入控制台-性能面板
在我们录制完毕之后,我们点开
Memory内存面板
面板按顺序是:
- js堆
- 文档
- 节点
- 监听器
- GPU 现在按照我们的图进行一下评比: 首先很长一段时间,我们的浏览器的执行都是平稳状态,如何多次起伏就是我们的事件触发+垃圾回收的情况
堆快照查找分离DOM
老规矩先上测试用例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>任务管理器监控内存变化</title>
</head>
<body>
<button id="btn">ADD</button>
<script type="text/javascript">
var tempEle
function test() {
var ul = document.createElement('ul')
for(var i = 0; i < 10; i++) {
var li = document.createElement('li')
ul.appendChild(li)
}
tempEle = ul
}
const btn = document.getElementById("btn");
btn.addEventListener('click', test)
</script>
</body>
</html>
判断是否存在频繁的垃圾回收
- TimeLine 中频繁的上升下降
- 任务管理器中数据频繁的增加减小