摘要
简单介绍 Chrome 开发者工具,科普一下 Chrome 开发者工具中一些可能不常用但实用的功能
前言
Chrome 开发者工具是一套内置于Google Chrome中的Web开发和调试工具,可用来对网站进行迭代、调试和分析(from: Google 开发者文档)
简介
首先我们可以通过多种方式来唤醒 Chrome 开发者工具
- 直接右上角菜单 -> 更多工具 -> 开发者工具
- 页面上右键,菜单里选检查(inspect)
或者通过快捷键
- Windows:ctrl + shift + I (或者 F12)
- Mac: cmd + opt + I
基础面板有这几个
- element 元素面板:主要就是查看和调试 DOM 和 CSS 相关的内容
- console 控制台面板:是一个 shell,可以跟 javascript 做交互
- source 源代码面板:可以查看当前页面使用的静态资源文件的代码,断点调试
- network 网络面板:用来查看和分析网络资源请求情况
- performace 性能面板:网站运行时的监控记录,可以用来分析网站性能情况(timeline)
- memory 内存面板:比 performance 做更深一层的记录
- application 应用面板:可以查看网页应用的所有资源,像 cookies,localstorage,web SQL 和缓存之类的东西
- security 安全面板:安全相关的内容,证书之类的
全局搜索代码
点击左边竖形排列的三个小点,选择 Search
点击搜索结果,会跳到具体的源码文件。它会搜索该网页下所有引入的文件。
Shadow DOM
通常一些比较复杂的原生 DOM 标签,像 <video>
,<audio>
还有 <input type="range">
,内部是由更多的基础标签构成的,默认情况下我们没办法查看内部构造和样式是怎么样的。
[图片上传失败...(image-98551a-1630031972107)]
在 setting里的 element 一栏把 Show user agent shadow DOM
勾上
[图片上传失败...(image-4298da-1630031972107)]
再重新回到 Element 面板查看页面上的元素,就会发现有很多新的东西出现了,以 <video>
标签为例
Ingore List
不知道你是否很多时候会遇到这种情况,在调试代码时需要逐步执行,由于遇到函数的时候会跳入函数的执行过程,很容易就在一些无关紧要的逻辑中徘徊许久,即使熟练地运用 step in 和 step out,也还是十分影响效率甚至导致问题难以排查出来(因为我们很多时候关心的是业务代码的实现问题)
这时候就要用到 Ingore List 的功能了,同样打开 setting,左侧导航选择 Ingore List
通过 Add pattern 添加忽略的文件名规则
这样在调试过程中遇到这些文件的内容就会当成黑盒处理,直接跳过
XHR/fetch Breakpoints
XHR breakpoints 用于异步请求的断点,点击加号图标添加新的断点规则,输入请求 URL 地址(片段),程序会在请求地址包含对应字符串的异步请求发出的位置自动停止
image.pngDOM Breakpoints
DOM breakpoint 可以在 DOM 元素被删除或修改的时候打断程序,在 Element 面板的 DOM 节点上右键,break on 一栏有三个选项
- subtree modification:在子节点被修改时中断
- attribute modification:在节点属性被修改时中断
- node removal:在节点被删除时中断
如上图为 tr 添加 attribute modification 的断点之后,在 DOM Breakpoint 就可以看到这个断点,随后 javascript 中如果有使这个节点属性class新增了hover ,程序就会中断
条件断点
DevTools支持条件断点,我们都知道在代码的行号上单击鼠标可以在当前行设置一个普通断点,程序执行到这里就会暂停。
接着,你可以在断点上右键然后选择 "Edit Breakpoint",这样就可以看到一个表达式输入框。在里面可以定义条件,如果条件为True
,断点就会生效
一个通常的表达式可能是total > 25
这种,然而在表达式写console.log
语句也是完全OK的。
这个条件表达式可以正常的工作,并且我们可以很明显看到console.log
语句在代码经过断点的时候执行了:
因为console.log
并没有真正的返回值,所以相当于返回了undefined
。这样对应的条件断点相当于不满足条件而不会被触发,程序在打印表达式信息后会继续的执行。所以这种做法感觉就相当于硬编码进去一个调试语句而不需要真的修改自己的代码。
Event Listener Breakpoints
4
Event Listener Breakpoints 可以在事件回调发生的时候中断
例如我们选中 mouse 鼠标类型中的 click 事件
那么当发生 click 事件的时候,会自动在相应的回调函数执行时中断
灵活运用上面这些方法,可以使平时代码问题排查更加灵活
Animation
除了样式的调试,动画也是可以检查和调试的,通过快捷键 command + shift + P
输入命令 show animation
打开动画面板
这时候动画面板就会开始监听页面上的动画,当页面上有动画发生的时候,会被记录下来记录
- 最顶上是控制按钮,可以清楚记录的动画,暂停监听,还有调整动画播放速度
- 紧接着是动画组,动画面板会判断哪些动画是相关联的并将它们分到同一个动画组
- 选中某个动画组可以看到包含的动画过程以及时间轴
- 我们可以在时间轴上定位到任一时刻的动画帧,也可以拖动左右两端的圆点来修改动画的延迟和周期
- 修改之后可以在属性面板看到对应的 css 样式
结合这个工具来进行动画编写和调试可以极大提高自己的效率,感兴趣的可以自己摸索一下
FPS meter & Paint flashing
image.png当用户跟页面发生交互的时候,页面上的内容有可能会发生变化,除了我们能明显观察到的视觉改变之外,由于 javascript 的操作,很可能页面上也会有其他内容被修改并重新渲染,这时候可以通过一些辅助工具来监测页面的运行情况
下面是比较实用的功能:
image.png- Paint flashing,实时高亮重绘区域(绿色)。
- Layout Shift Regions,实时高亮重排(重新布局)区域(紫色)。
- Layer borders,将合成层用边框标出来(橙色、橄榄色、青色)。
- Frame Rendering Stats,显示 GPU 的信息,还有实时 FPS 显示。
- Scrolling performance issues, 高亮具有滚动、点击等事件的元素或者区域(黄色)
- Core Web Vitals,使用者体验量化
- LCP 显示最大内容元素所需时间 (衡量网站初次载入速度)
- FID 首次输入延迟时间 (衡量网站互动顺畅程度)
- CLS 累计版面配置移转 (衡量网页元件视觉稳定性
通过 FPS meter 可以看到当前页面的实时帧率,正常情况下页面应该是处于 60 fps 的状态,当页面更新不流畅的时候,fps 数值会下降,曲线出现波动。我们可以清楚地看到页面操作造成了哪些位置的更新,结合前面 FPS meter,更方便我们定位页面性能下降的原因。
同时开启Paint flashing。这样我们可以清楚地看到页面操作造成了哪些位置的更新,结合前面 FPS meter,更方便我们定位页面性能下降的原因
内存分析类型
内存快照: 展示了整个页面的JavaScript对象以及DOM节点的内存分配
打开控制台上的Memory面板,会发现相应的录制按钮等操作。
开始录制前先点击下垃圾回收-->点击开始录制。
如果JS堆内存动态分配时间线,结束之前要再点击下垃圾回收,再结束录制
上面有三个按钮:
- Heap snapshot - 用以打印堆快照,堆快照文件显示页面的 javascript 对象和相关 DOM 节点之间的内存分配
- Allocation instrumentation on timeline - 在时间轴上记录内存信息,随着时间变化记录内存信息。
- Allocation sampling - 内存信息采样,使用采样的方法记录内存分配。此配置文件类型具有最小的性能开销,可用于长时间运行的操作。它提供了由 javascript 执行堆栈细分的良好近似值分配。
1. Summary 总览视图
可以显示按构造函数名称分组的对象。使用此视图可以根据按构造函数名称分组的类型深入了解对象(及其内存使用),适用于跟踪 DOM 泄漏。
内存快照中,展示了整个页面的JavaScript对象以及DOM节点的内存分配
image.png image.png
- Contructor - 表示使用此构造函数创建的所有对象
- Distance - 显示使用节点最短简单路径时距根节点的距离
- Shallow Size - 显示通过特定构造函数创建的所有对象浅层大小的总和。浅层- - 大小是指对象自身占用的内存大小(一般来说,数组和字符串的浅层大小比较大)
- Retained Size - 显示同一组对象中最大的保留大小。对象的最大保留内存,保留内存是指对象被删除后可以释放的那部分内存。
常见的顶层构造函数:
- (global property):全局对象和普通对象的中间对象,和常规思路不同。比如在Window上定义了一个Person对象,那么他们之间的关系就是[global] => - (global property) => Person。之所以使用中间对象,是出于性能的考虑。
- (closure):使用函数闭包的对象。
- (array, string, number, regexp):一系列对象类型,其属性指向Array/String/Number/Regexp。
- HTMLDivElement/HTMLAnchorElement/DocumentFragment:元素的引用或者代码引用的指定文档对象。
快照可以用来发现DOM泄露。在Class filter(类过滤器)文本框中输入Detached可以搜索分离的DOM树。如果分离节点被JS引用,有可能就是泄露点。
如下代码,class filter中查找string,在string列表中找到'Hello World!'可以查看到testArray的内存引用。
var testArray = [ {value: 'Hello World!'} ];
最后,根据上面的图来分析一下上面代码产生的效果,根据 js 的类型和引用的关系来分析,变量 testArray 在列表中的情况是:
image.png基础类型 string 值为 hello ,内存标记是 string@94357,这个 string 值存在于 Object @99423 对象上的 value 属性上;
Object @99423 在 Object 列表里,在 Array @356493 的索引 0 位置存在该对象的引用;
Array @356493 在 Window / @353829 对象上存在引用,属性名为"testArray";
Window / @353829 是个 Windows 对象,在 Windows 列表里。
"hello" -> 在(string)列表里 -> string@94357 -> value in Object @99423
Object -> 在 Object 列表里 -> [0] in Array @108181
Array -> 在(array)列表里 -> testArray in Window / @94129
Windows -> 在 Windows 列表里 -> Window / @94129
2. Comparison 对比视图
显示两个快照之间的不同。使用此视图可以比较两个(或多个)内存快照在某个操作前后的差异。检查已释放内存的变化和参考计数,可以确认是否存在内存泄漏及其原因
- New - Comparison 特有 - 新增项
- Deleted - Comparison 特有 - 删除项
- Delta - Comparison 特有 - 增量
- Alloc. Size - Comparison 特有 - 内存分配大小
- Freed Size - Comparison 特有 - 释放大小
- Size Delta - Comparison 特有 - 内存增量
var testArray = [ {value: 'Hello World!'} ];
function doSomething() { testArray.push({ value: 'Hello Everyone!' }) }
document.querySelector('#btn').addEventListener('click', doSomething)
点击按钮后,数组中 push 了新的一项对象
image.png
3. Containment 内容视图
查看内存内容。由顶级对象作为入口,更适合查看对象结构,有助于分析对象的引用情况。适用于分析闭包以及深入分析对象。
4. Statistics 统计视图
总览内存的统计信息
5. 分配时间线
看完静态的快照,再来看看动态的。
可以持续的记录堆分配的情况,随着时间变化记录内存信息
var testArray = [ {value: 'Hello World!'} ];
var count = 1;
function doSomething() {
// 每次点击 字符串长度都以上一次为基础增加到5倍,拉大差异突出效果,并且之后在字符串头部加上count值做区分
count *= 5
var str = new Array(count * 10).join(':')
testArray.push({
value: count + str
})
}
document.querySelector('#btn').addEventListener('click', doSomething)
每条线的高度与最近分配的对象大小对应,竖线的颜色表示这些对象是否仍然显示在最终的堆快照中。
蓝色竖线表示在时间线最后对象仍然显示,灰色竖线表示对象已在时间线期间分配,但曾对其进行过垃圾回收。
image.png
参考资料:
网友评论