Performance 工具
为什么要使用
GC的目的是为了实现内存空间的良性循环,js中并没有提供操作内存的api,所以当我们写代码的时候无法判断是否合理使用了内存空间,performance 就提供了时刻监控内存的方式。
内存问题
- 页面出现延迟加载或经常性暂停,可能存在频繁的GC操作,可以通过内存变化图进行分析
- 页面持续性出现糟糕的性能,可能出现了内存膨胀,指当前界面为了达到最佳的使用速度而去申请了一定的内存空间,但是这个内存空间远超过了当前设备本身(和设备的硬件相关)能提供的大小
- 页面的性能随时间延长越来越差,可能出现了内存泄露,内存使用持续升高,使内存空间越来越少
1. 浏览器任务管理器
- 模拟一个 html 页面,代码如下
<body>
<button id="btn">Add</button>
<script>
const oBtn = document.getElementById('btn')
oBtn.onclick = function() {
let arrList = new Array(1000000)
}
</script>
</body>
- 在浏览器中打开这个 html 页面,通过 shift + esc 快捷键调出浏览器任务管理器,可以看到下面的图片(如果没有 js 内存项,可以右键进行选择)
- 内存占用空间:DOM 节点所占据的内存,如果这个内存一直增大,则表示界面正在不断创建新 DOM
- javaScript使用的内存: 表示 js 中的堆内存,小括号里的值表示的是所有可达对象正在使用的内存大小,如果这个数值一直增大,则表示当前界面中正在创建新对象或现有对象在不断增长
可以看到打开界面之后javaScript内存中的值一直不变,就是没有对象在增长的
- 触发 Add 按钮,可以看到 js 内存明显变大
通过观察这个内存的变化,我们可以看出代码是否存在问题,但具体问题难以定位。
2. Timeline 时序图记录
- 模拟一个 html 页面,代码如下
<button id="btn">Add</button>
<script>
const arrList = []
function test() {
for(let i = 0;i< 100000; i++){
document.body.appendChild(document.createElement('p'))
}
arrList.push(new Array(1000000).join('x'))
}
document.getElementById('btn').addEventListener('click', test)
</script>
- 调出控制台,找到perfprmance面板,开始记录
- 触发3次 Add 按钮,然后停止记录,根据图示查看js内存的变化
根据这个图表可以分析:
- 一开始点击 Add 按钮前处于平稳的状态,没有太多的内存消耗
- 第一次点击 Add 之后,内存瞬间暴涨,然后保持处于一个高峰状态
- 当脚本运行稳定之后,GC 可能在某个时间点开始工作,发现一些非活动对象并进行回收,所以高峰之后会有一个下降的过程
- 在下降的区间中会有一些小的波动,属于正常的开销,后面的点击也会造成同样的暴涨和下降。
- 这样有升有降是正常的内存变化,升就是申请内存,降就是GC回收,如果一直保持上涨,就表示内存有不正常的消耗了,有可能是内存泄漏。
- 当发现问题的时候,可以拖动上方的时序图,找到出问题的毫秒页面的样子,从而定位问题
3. 堆快照查找分离 DOM
分离DOM:脱离DOM树,但是在js中还在被引用的DOM节点。这种DOM在页面上看不见,但是在内存中还占据着空间,这就是一种内存泄漏。
- 模拟一个 html 页面,代码如下
<button id="btn">Add</button>
<script>
var tmpEle
function test() {
var ul = document.createElement('ul')
for(let i = 0;i< 10; i++){
var li = document.createElement('li')
ul.appendChild(li)
}
tmpEle = ul
// tmpEle= null 直接置空既可以解决分离DOM的问题
}
document.getElementById('btn').addEventListener('click', test)
</script>
- 调出控制台,找到memory面板,拍摄堆快照(Heap snapshot -> take snapshot)
- 拍摄的照片中就是当前活动对象的展示,可以搜索detached(分离DOM),发现没有相关的内容
- 触发 Add 按钮,再次拍摄堆快照,同样搜索detached,可以发现搜索结果中有了内容,就是我们在 js 中添加的 DOM节点(分离DOM)
判断是否存在频繁的 GC 操作
- timline中频繁的上升下降
- 任务管理器中数据频繁的增加减小
学习自拉钩教育前端视频