Devtools 老师傅养成[6] - Performance 面板
本文结构
- 系列文相关
- Performance面板概览
- RAIL模型
- 控制区
- FPS图表
- CPU图表
- Screenshots
- HEAP
- Frames
- FPS仪表工具
- Main
- 性能相关扩展
- 浏览器并发请求数
本文共计:2108字15图
预计阅读时间:6min10s
系列文相关
- 本文基于 chrome 浏览器版本 73.0.3683.103(正式版本)总结
- 本文目的:关于【devtools 能做什么】建立完善的知识结构,至于怎么做,请查阅官方文档;工具类知识需要实践,建议阅读本文时打开 sample[1]和 devtools 操作一遍
- 参考 1:google developers 官方文档[2]
- 参考 2:来自作者 Jon Kuoerman 在 FrontEndMaster 的 Mastering Chrome Developer Tools v2 课程[3]
- 参考 3:来自 作者 Tomek Sułkowski 在 medium 的系列文章[4]
- Devtools脑图.png[5]
Performance面板概览
- performance 面板可以用于分析
运行时性能
(运行时强调的是与页面加载性能相区分) - 以隐身模式打开网页 (隐身模式可确保 Chrome 以干净的状态运行。例如,排除扩展对性能测量的影响
- Janky Animation demo :性能测试 demo[6]
- 视图 overview:
performance面板概览
RAIL 模型
- RAIL 模型[7]是一种性能模型,定义了四个维度的性能分析指标
-
Response
:在100 毫秒
以内响应(例如从点按到绘制) -
Animation
:每秒生成 60 帧,每个帧的工作(从 JS 到绘制)完成时间小于 16 毫秒,达到人眼顺滑(例如滚动 拖动都是动画类型)(因为浏览器需要花费时间将新帧绘制到屏幕上,只有10 毫秒
来执行代码) -
Idle
:利用空闲时间完成推迟的工作(要实现第一条 response 在 100ms 内响应,Main 主线程 JS 工作应该小于50ms
,剩余的时间将主线程的控制从 js 返回给浏览器执行其像素管道、对用户输入作出反应等,因此最佳实践是将 js 的工作分成不大于 50 毫秒的块,如果用户开始交互,优先级最高的事项是响应用户。 -
Load
:在1000 毫秒
以内呈现内容(无需完整加载,启用渐进式渲染,将非必需的加载推迟到空闲时间段 - 通过 performance 面板,可以得到这四个维度的分析数据
控制区
- 点击
录制按钮
或者开始录制并刷新页面按钮
,可以在控制区下方得到全部性能分析结果 - 其中除了最下方的详细信息窗格以外,分析结果都是以时间为轴
- 可以在 overview 窗格拖动鼠标,选择某段时间的分析结果
- 滚动鼠标滚轮,缩放/移动选中事件
- 在火焰图窗格,按住
shift
,滚动鼠标滚轮,可以上下 - 在火焰图窗格,也可以直接左右拖动图表
- 或者用
W A S D
按键控制缩放移动 -
Disable JavaScript samples
默认情况,在Main
主线程的火焰图中,会详细记录 js 函数之间的调用栈,可以开启此选项禁用调用栈记录 -
Enable advanced paint instrumentation
启用高级绘图工具,可以在分析结果的Frames
中的每一帧的详细结果中看到Layer
选项卡,其中有选中帧的详细图层信息;也可以在Main
主线程火焰图中选中绿色的Paint
事件,在最底部详细信息的Paint Profile
选项卡中,看到详细的页面绘制过程分析 -
Collect garbage
控制器最右的垃圾桶图标,是强制执行垃圾回收,对于监控内存比较有用
FPS 图表 - Frames Per Seconds
- FPS 图表中,绿色代表帧率高低,参考
RAIL
模型,帧率>=60 时,用户能体验的顺滑的网页 - 红色出现 代表有掉帧情况
CPU 图表
- CPU 图表中,不同的颜色代表不同事件对 CPU 的占用,颜色信息如图
- 当 CPU 长时间被占满,就是当前网页性能需要优化的信号
SCREENSHOTS
- 鼠标在
FPS,CPU,NET
图表悬浮时,会展示出鼠标对应时间点的网页截屏,左右移动鼠标可以看到网页变化的重播效果
HEAP
- 在 HEAP 图表中可以看到 JS 内存占用情况,与下方的 memory 窗格中的
JS Heap
相对应 - 在 Memory 窗格还可以看到 Document 文档、Nodes DOM 节点、监听器、GPU 内存的习份内存统计
Frames
- 点击三角箭头展开
Frames
区域,鼠标悬浮/点击绿色方块,可以看到该特定帧的帧率和渲染耗时,当 FPS 低于 60,表明当前帧的渲染效率较低
FPS 仪表工具
- 通过
more -> more tools -> Rendering
或者ctrl+shift+p -> rendering
打开Rendering
面板
- 启用
FPS meter
,即可看到的页面实时帧率
Mian
- 点击三角箭头展开
Main
区域,可以看到主线程上事件的火焰图
- x 轴是时间,每一块代表一个事件,y 轴代表堆栈,事件的上下堆叠,代表上层事件引发/调用了下层事件
- 通过调用堆栈,可以找出导致低性能的事件及其源码位置
- 当事件块出现红色三角,可以点击三角查看该事件的性能相关警告信息,并定位到引起警告的代码
- 点击
Animation Frame Fired
事件,可以在最下方Summary
窗格查看触发动画事件的详细信息,点击Initiator
后的reveal
链接,会高亮到引起动画事件的事件
性能相关扩展
- 网页性能-性能模型/加载/渲染/审计/优化[8]
- the-anatomy-of-a-frame - 一个帧的剖析[9]
- 常见的时间线事件参考[10]
浏览器并发请求数
- 现象:同一时间针对同一域名下的请求有一定数量限制。超过限制数目的请求会被阻塞。
- 原因:基于端口数量和线程切换开销的考虑,浏览器不可能无限量的并发请求。
- 导致:有大量请求的站点,响应较慢,因为并发请求会被阻塞。
不同浏览器的限制数
- 解决方法:
- 用不同域名(hash domain,cookie free) 例如知乎的图片都是放在zhiimg.com域名下获取的。cookie free是指,例如知乎主站zhihu.com域名下有很多cookie,换成zhihuimg.com请求图片时,就不会把zhihu上的cookie发过去,减小所需带宽。
- 减少请求数 雪碧图 合并压缩css/js(另一个原因是为了减少重绘) 利用Cache-Control等缓存静态资源,在更新静态资源时使用不同url或文件名带上版本 懒加载,出现再加载
参考资料
[1]
sample: https://masteringdevtools.com/
[2]
google developers 官方文档: https://developers.google.com/web/tools/chrome-devtools/
[3]
Mastering Chrome Developer Tools v2 课程: https://frontendmasters.com/courses/chrome-dev-tools-v2
[4]
系列文章: https://medium.com/@tomsu
[5]
Devtools脑图.png: https://i.loli.net/2019/04/19/5cb95639a9f73.png
[6]
Janky Animation demo :性能测试 demo: https://googlechrome.github.io/devtools-samples/jank/
[7]
RAIL 模型: https://developers.google.com/web/fundamentals/performance/rail
[8]
网页性能-性能模型/加载/渲染/审计/优化: https://developers.google.com/web/fundamentals/performance/why-performance-matters/
[9]
the-anatomy-of-a-frame - 一个帧的剖析: https://aerotwist.com/blog/the-anatomy-of-a-frame/
[10]
常见的时间线事件参考: https://developers.google.com/web/tools/chrome-devtools/evaluate-performance/performance-reference
- END -
- cocos2dx-v3.5 2048 (一): 项目架构
- cocos2dx-v3.5 2048 (二): GameTool的设计与实现
- cocos2dx-v3.5 2048(三):菜单实现
- 2017 LCTF WriteUp 4篇
- cocos2dx-v3.4 2048(四):单元格的设计与实现
- javascript - 闭包
- Java 反射简单实例
- [安全入门教学]如何分析海洋CMS漏洞
- Java 回调函数的使用
- Android 配置Freeline教程
- 如何用JS写一个table组件 | 作业讲解
- Mac 高效工作指南
- Jarvis OJ平台basic部分writeup
- React Native之打包
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- prometheus-operator 监控 k8s 外部集群
- Kubernetes 通过statefulset部署redis cluster集群
- 猿实战13——实现你没听说过的前台类目
- 猿实战14——前台类目之广告牌设置
- 猿实战15——关联你所不明白的前后台类目
- 完美解决方案-雪花算法ID到前端之后精度丢失问题
- 猿实战16——承运商之搭建你的运费基石
- List对象去重及按属性去重的8种方法-java基础总结第六篇
- 总结java创建文件夹的4种方法及其优缺点-JAVA IO基础总结第三篇
- 总结java从文件中读取数据的6种方法-JAVA IO基础总结第二篇
- 总结java中文件拷贝剪切的5种方式-JAVA IO基础总结第五篇
- 总结java中删除文件或文件夹的7种方法-JAVA IO基础总结第四篇
- 总结java中创建并写文件的五种方式-JAVA IO基础总结第一篇
- 8成以上的java线程状态图都画错了,看看这个-图解java并发第二篇
- 特殊数据格式处理-JSON框架Jackson精解第2篇