1.三大面板
1.概览面板
- FPS(页面帧速):出现红色点,证明一帧渲染时间过长,会导致卡顿
- NET网络请求:如果显示过长,证明网络或接口可能有异常
- CPU:图形占用过大,证明主线程执行时间过长,会影响其他任务执行
- HEAP:内存曲线一直增高,没有降下来可能是内存泄露 可以通过鼠标滚动或“WASD”四个键来可以调整选择范围
2.性能面板
- Main渲染主线程的任务执行过程
- Compositor 合成线程的任务执行过程
- Raster合成线程中光栅化线程池,多条线程
- GPU: GPU进程主线程的任务执行过程
- Frame显示的每一视图帧
- Network网络请求详情
- Timings 显示关键的FP、LCP、DOMContentLoaded、Onload节点
- Chrome_ChildIOThread 渲染进程中的IO线程,用于收发不同进程中的消息
- Interactions 用来记录用户交互操作,比如点击鼠标、输入文字等交互信息
3.详情面板
在性能面板点击对应的指标,详情会显示具体的信息
1. summary统计
2. bottom-up执行时间排序显示
3. call tree 调用嵌套显示
4. event log所有log信息
通过loading、scripting、rendering、painting进行快速过滤
4.1 loading 网络请求+渲染进程解析
4.2 scripting js执行,各种dom生命周期回调
4.3 rendering 渲染
4.4 painting 绘制输出
2.性能面板-Main渲染主线程
1.包含各种复杂的任务
- 渲染流水线任务
- JavaScript函数执行
- V8的垃圾回收
- 定时器设置的回调任务
2.标记色区分
- 灰色:task主任务
- 橙色/粉色:子任务,可互相嵌套
- 蓝色:解析html
- 紫色:样式计算
- 绿色:绘制
3.完整的流程
完成流程包含 导航阶段,解析html阶段,合成生成位图阶段,3个阶段。
1.导航阶段
- 页面执行pagehide、visibilitychange和unload等事件
- Sendrequest发送请求
- ReceiveRespone过程接受到http响应头
- ReciveData已经接受到数据
- Finishload 表示网络请求已结束
2. 解析html阶段
- 解析js- EvaluteScript
- ComplieScript编译脚本
- 程序执行,调用匿名函数anonymous
- 可能触发了dom节点变化
- 再次触发ParserHTML
- 生成cssom,解析css,ReculateStyle
- 先执行页面dom事件 readyStateChange、DOMContentLoaded、load、pageshow
3. 合成生成位图阶段
- 执行布局 Layout
- 更新层树 UpdateLayerTree
- 准备绘制列表了Paint
- 根据绘制列表来生成相应图层CompositeLayers
- 合成线程Compositor的对执行记录逐个处理
- 合成线程维护Raster 线程RasterizePaint
- Rasterize线程传输数据给 GPU线程
- GPU生成图像显示到显示器
4. 分析demo
1.重排重绘demo
<html>
<head>
<title>性能分析</title>
<style>
.box {
background-color: blue;
height: 50px;
width: 50px;
}
.box2 {
background-color: red;
height: 50px;
width: 50px;
}
</style>
</head>
<body>
<div class="box" id="containerId"></div>
<script>
function setNewArea() {
let containerId = document.getElementById("containerId")
containerId.setAttribute('class', 'box2') //设置样式触发重绘
let el = document.createElement('div')
el.innerHTML = '<div class="box"></div>'
document.body.append(el)//设置样式触发重排
}
setNewArea()
</script>
</body>
</html>
通过刷新按钮进行诊断
这里点击后要快速点击stop,不然生成报告过长,不方便查看
生成的报告如下:
点击main的空白处,则显示所有的main信息
下面是顺序调用的方法
2.多<script>
的demo
1.同一个<script>
多个微任务
<html>
<head>
<script>
Promise.resolve().then(() => { console.log("Promise1执行") })
console.log("xxxx")
Promise.resolve().then(() => { console.log("Promise2执行") })
</script>
</head>
<body>
</body>
</html>
所有微任务会放在同一个执行上下文中执行。
2.不同<script>
的微任务执行
<html>
<head>
<script>
Promise.resolve().then(() => { console.log("Promise1执行") })
</script>
<script>
Promise.resolve().then(() => { console.log("Promise2执行") })
</script>
</head>
<body>
</body>
</html>
两个微任务分别在不同的执行上下文中执行,会导致执行效率降低。