好强好强
转载自:https://www.cnblogs.com/vvjiang/archive/2020/02/27/12370112.html
前言
工欲善其事,必先利其器。
在前端工作中,我们常常使用到Chrome开发者工具去做各种各样的事情。
但是您真的了解这些开发者工具吗?
官方文档还是挺详细的:chrome-devtools文档。
但是文档中仍然会有一些功能没有描述到或者被一笔带过。
而我的这篇指南,会略过那些一目了然的功能以及一些容易替代的方案,写一写那些您可能不太了解的功能和文档描述不清的功能。
阅读本篇文章需要有一定的前端基础。
媒体查询功能
Chrome开发者工具不仅可以调试web应用,还可以模拟各种终端设备。
通过激活下图中红框部位开启设备工具栏。
工具栏可以切换模拟各种型号的设备,也可以通过自适应模式(Responsive)来调整视口。
这里通过更多工具中的Show media queries查看媒体查询:
图中蓝色区块为最大宽度断点,黄色区块为最小宽度断点。
右键相应区块还可以跳转到具体的css文件中的媒体查询代码。
模拟传感器(地理位置,手机朝向)
点击更多工具中的Sensors(传感器)
在这里可以模拟地理位置,手机朝向
生成页面全尺寸快照图片
通过下图操作,可以生成一张页面全尺寸的快照。
而它上面那个选项是生成当前视口大小的图片。
控制台快速获取元素面板的元素
在元素面板上选中一个元素后:
细心的朋友会发现后面总是会出现一个== $0的提示。
此时在控制台输入$0,实际上就可以获取到该元素。
通过这种方式,即使对于那些没有class和id的元素,我们也可以在控制台快速获取并使用。
您可能会问:那我要是想在控制台调用多个这样的元素呢?
选中元素,右键,选择选项:Store as global variable。
此时会将选中的元素存储在一个临时变量中,并自动在控制台输出这个变量的名字。
页面跳转到元素面板指定的元素
某些时候页面元素出现BUG,不知道跑到哪去了,我们需要页面跳转到这个元素所在的位置。
如果我们知道它的id或者class,我们可以通过在控制台输入js命令去跳转:
document.querySelector('.icon-cool').scrollIntoView()
当然也可以通过我们上面说到的$0做到:
$0.scrollIntoView()
但是有个更简单的办法,那就是右键元素面板上的指定元素,然后点击Scroll into view的选项。
DOM断点
同样右键元素面板上的元素,发现有个Break on的选项,这里可以打DOM断点。
从上往下依次是子节点改变时断下,元素属性改变时断下,节点移除时断下。
打下断点后,在左侧会有断点标识,右侧的DOM Breakpoints也会有相应的显示。
点击DOM Breakpoints的相应DOM断点,元素面板也会定位到相应元素。
当js去修改指定元素的DOM结构时,就会在修改的位置断下。
这种断点很方便查找到究竟是哪里对页面元素进行了修改。
元素事件侦听器
在元素面板选中元素,右侧的Event Listeners会显示该元素上的事件。
如果勾选了Ancestors(祖先),那么会展示祖先节点的事件,通常不需要勾选这个。
点击事件右侧的链接可以跳转到附加事件的代码。
通常一些js框架或库(比如jQeury)会将原生DOM事件进行封装,而这会导致我们通过元素事件侦听器跳转到的代码是这些库文件的封装代码。
不过如果我们勾选了Framework listeners(框架侦听器),那么就会跳转到我们使用库文件事件API的地方,而不是库文件里。
Framework listeners对于jQuery这样对事件进行简单封装的特别好用,但是对于React这种的话作用有限。
查看当前页面对css和js使用覆盖率
通过以下方式打开Coverage选项卡,这个可以查看当前页面对css和js的使用覆盖率。
点击左上角按钮开始记录:
如上图可以单纯查看css还是js,或者都查看。
选中单个文件,还可以查看具体是哪些代码或者css没有使用到。
记录期间,我们做各种操作,都会影响到这个使用覆盖率的变动。
对于现在常用的单页面应用而言,尤为有效,因为切换页面实际并没有改变html,所以这个记录一直有效。
对于以往采用jQuery的多页面应用而言,当切换了页面之后,记录就重新开始了。
不过不管是单页面还是多页面,通过这种方式都是可以查看相应的js和css的使用覆盖率的,对于优化css和js,删除无用的废代码,以及代码文件拆分都很有帮助。
使用本地文件调试生产环境网站代码
我们调试生产环境的BUG,经常需要修改样式或者js,但是页面一刷新这些东西就又还原了。
所以这里有个神技,可以将生产环境的引用文件进行本地化,然后修改本地化后的文件进行调试。
首先我们需要打开在Source面板下左侧的Overrides选项卡,选择一个本地文件夹作为覆盖文件夹。
这里我选择了一个名为test的文件夹。
然后我们切换到Source面板的Page选项卡,选中某个文件,然后右键,选中选项Save for overrides。
此时切回Overrides选项卡,发现test文件夹中已存在相关的js文件。
修改该文件的js内容,再保存,即使刷新之后修改后的内容依然会生效,并且页面会加载我们修改之后的js文件。
Animation动画检查器
通过下图方式可以打开Animation检查器:
这个检查器自动开始监听页面上的动画,但是这个时候动画已经加载完了,监听不到,需要我们重新刷新页面才行。
选中其中的一个动画,会显示如下图的效果:
通过它我们可以查看和调整CSS动画和过渡的各种效果。
Rendering选项卡(高亮重排重绘合成层,fps和gpu占用,滚动优化,媒体查询模拟如打印)
Rendering选项卡,顾名思义是做一些渲染相关的事。
通过下图方式打开Rendering选项卡:
下面是选项卡的界面:
- Paint flashing 高亮页面重绘区域。
- Layout Shift Regions 高亮布局变动区域(重排)。
-
Layer borders 高亮合成层边框,对于减少合成层还是挺好用的。
以上三点,如果不太清楚,可以看看这篇好文:浏览器渲染详细过程:重绘、重排和 composite 只是冰山一角。
简略一点来说,渲染过程就是DOM树+样式树,合成渲染树,渲染树加上层叠遮罩之类的再演变为Layer树,Layer树再合成为为Graphics Layers即Composite Layer,再丢给GPU进行处理。
-
Scrolling Performance Issues 用于优化滚动性能问题。
这个是用来高亮可能会影响滚动性能的元素,这些元素主要指绑定了scroll事件和touch事件的元素。
scroll大家可能会比较理解,touch的话其实也可以影响滚动性能,最直观的就是只要我们禁止了某元素上touch的事件中禁止浏览器默认行为,那么就不会再触发scroll事件。
而touch的影响还不止如此,比如将touch-action改为manipulation可以减少移动端浏览器在用户点击事件的延迟,但是这个东西会影响到滚动时的性能。
当您开Scrolling Performance Issues发现页面上一堆高亮的touch事件时,可以考虑touch-action:auto来去除。
具体的优化可能得根据实际情况去处理,哪里有问题优化哪里,取得一个平衡即可。
- Highlight ad frames 高亮用于广告的iframe(试了下,谷歌的推广广告识别没问题,百度的没测)。
- Hit-test borders 展示点击测试的区域。(鸡肋,请忘记)。
- Emulate CSS media type 模拟媒体查询是打印还是终端屏幕。
- Emulate CSS media feature prefers-color-scheme 模拟媒体查询的系统主题,具体参考prefers-color-scheme。
-
Emulate CSS media feature prefers-reduced-momition 模拟媒体查询的开启动画减弱功能,具体参考prefers-reduced-motion。
保留页面控制台记录和网络请求记录
Chrome的Console面板和Network面板都有Preserve Log这个选项,当勾选了这个选项后,会保留当前选项卡的控制台和请求记录。
对于涉及到多个页面间跳转的问题,这个功能很有帮助。
切换控制台的执行环境(iframe中运行脚本)
Console面板上面有个名为Javascript contexts的选择器,一般值默认为top。
top表示当前执行环境为当前页面,而如果想切换到当前页面各个iframe,就需要进行相应切换。
比如,在博客园首页,我们可以切换到各个广告iframe的运行环境。
与此相关的一个功能是,只输出所选运行环境的打印日志:
点击右上角齿轮打开控制台设置,勾选Selected context only即可。
控制台的实时表达式
在控制台面板有个眼睛一样的图标,名为:Create live express(创建实时表达式)。
点击它创建一个入上图红框所示的小面板。
输入表达式可以自动监控这个表达式。
比如如果实时表达式为a,如果a的值变动了,那么这个实时表达式的值也会变动。
控制台的API
我这里直接给开发者文档的地址了,毕竟有点多,建议了解一下,知道有哪些功能即可。
比如monitor(监听函数执行)和monitorEvent(监听事件)还是有些用处的。
可重复执行的控制台脚本片段
如果您在调试BUG时总是在控制台多次重复执行大段的相同的JS代码。
那么您可以考虑用Snippet(片段)。
这个东西虽然作用于控制台,但是却不是在Console面板,而是在Source面板。
如图所示,我们通过点击New snippet新建了一个叫TestSnippet的代码片段。
然后我们可以点击右下角的运行或者用Ctrl+Enter在控制台运行这段代码片段。
XHR/Fetch 断点
在Sources面板,右侧会显示XHR/fetch Breakpoints。
点击加号,可以输入字符,如果输入mynameis,那么就会在ajax请求或者fetch请求的URI包含mynameis时断下。
如果不填,那么也会新增一行,表示断下所有的ajax请求和fetch请求。
事件侦听器断点
在Sources面板,右侧会显示Event Listener Breakpoints。
顾名思义,用来给相应事件打断点的。
这里基本上收录了所有的事件,连WebAudio,Worker,Timer的都有。
异常断点
同样在Sources面板右侧会显示异常断点的图标:
激活后可以在各个未捕获的异常处断下,激活后还可以通过进一步勾选 Pause on caught exceptions在已捕获的异常处也断下。
脚本黑盒化(Blackbox script)
在Source面板,选中某js脚本文件后右键,或者在调试的堆栈中右键,都会出现一个Blackbox script选项。
点击这个选项,可以让我们在调试时认为此脚本总是对的,忽略此脚本,不论是调试过程或者堆栈都不会进入这个脚本。
一般用来黑盒化一些js库,比如jQuery或者lodash之类的。
网络面板的截图功能
Network面板中有个截屏功能,开启之后再重新加载页面,就会如下图显示各个时间段下的截图。
双击这些缩略图,可以放大查看当时页面的具体样子。
单击缩略图,可以显示当前缩略图时间点前发送的所有请求。
网络面板关于网络请求的一些优化
同域名请求数量限制(HTTP/1.0或HTTP/1.1)
如果网络请求出现排队的情况,那么说明是在单个域上提出了太多请求。
在HTTP/1.0或HTTP/1.1连接上,Chrome每个主机最多允许六个同步TCP连接。
想要优化这一点,可以将关键请求提前,不关键请求延后。
如果都是关键请求,那么可以尝试使用HTTP 2。(在Network面板可以展示Protocol显示)
如果条件有限,可以将这些请求放在不同的域名上,然后用nginx指向同一个源头,这样同样可以解决这个问题
请求第一个字节的时间过长 Time To First Byte (TTFB)
我们查看一下博客园首页的请求。
可以看见每个请求后面都有一个绿色的区域,这个绿色区域表示每个请求的Time To First Byte (TTFB),即请求第一个字节的时间。
点开一个具体的请求,看一下:
通常原因是浏览器与服务端的请求连接速度很慢,或者服务端的请求响应过慢。
简单来说,就是网络连接慢,或者是服务端代码写得太辣鸡。
如果是网络连接慢,可以用CDN,或者换个近一些的服务器。
如果是服务端响应慢,那么可以考虑缓存,或者优化接口,那就是服务端的事情了。
内容下载慢
这里直接用Chrome官网的图片吧:
一般表现于请求的下载时间过长,也就是请求后面跟着的蓝条。
原因基本上就是js或者其它的一些资源文件太大了,导致下载过慢。
因为用的是100M的网,所以我比较难找这样的例子,不过用浏览器的模拟3G网的话,其实博客园很多那种二次元风格,自带一张二次元大背景的博客都会出现这种现象。
这种建议将图片尺寸压缩一下。
网络面板时间分解阶段说明
这里列出Timing选项卡可以看到的各个时间阶段:
- Queueing(排队):浏览器在以下情况下将请求排队:
- 有更高优先级的请求。
- 已为该来源打开了六个TCP连接。仅适用于HTTP/1.0和HTTP/1.1。
- 浏览器正在磁盘缓存中短暂分配空间
- Stalled:出于Queueing中描述的任何原因,该请求都可能被暂停
- DNS Lookup:浏览器正在解析请求的IP地址
- Proxy negotiation:浏览器正在与代理服务器协商请求
- Request sent:请求发送时间
- ServiceWorker Preparation:浏览器正在启动service worker
- Request to ServiceWorker:请求发送到service worker的时间
- Waiting (TTFB): 浏览器等待第一个字节响应的时间
- Content Download:响应内容下载时间
- Receiving Push:浏览器正在通过HTTP/2服务器推送接收此响应的数据
- Reading Push: 浏览器正在读取先前接收的本地数据。
查看请求的依赖关系
各个请求都有着它们各自的依赖关系,最常见的是图片、js和css依赖html请求。
只有在html请求完毕才会在上面慢慢加载这些资源文件。
同样以博客园为例:
我们按住Shift,鼠标浮动到analytics.js这个请求上,可以看到www.cnblogs.com那个请求变绿了,collect那个请求变红了。
这个表示analytics.js这个请求,依赖于www.cnblogs.com,而collect这个请求依赖于analytics.js。
WebSocket消息的监控
如下图:
我们通过Network面板上的类型筛选到WebSocket请求,点开这个请求,我们可以看到相应的消息。
Audit面板
关于Audit面板这里不讲使用方法,主要是太多了。
但是这个东西确实很方便,这里是:参考文档。
这里要说的是这个东西需要翻墙,如果翻不了,可以装个LightHouse的扩展插件,如果下不了或者不想更新麻烦,有个更好的办法。
使用微软的Edge,基于Chromium的那个,然后在它的商店装个SiteTool的扩展插件即可。
Performance面板性能分析
Performance面板主要是用来分析运行时的性能。加载的用Audit即可。
关于怎么使用这里就太多了,咱们先挑最简单的一个流程来讲。
我们首先看一下一个性能良好的结果图:
然后我们再将CPU变慢6倍,再看一下性能不好的结果图:
FPS概览
对比第一张图,我们发现第二张图关于FPS那一行出现了很多红色,并且绿色的高度明显降低。
这表示它的FPS值很低,一般给用户的感受就是很卡。出现了红色表示会影响到用户体验。
CPU概览
同时我们再对比上面两张图,发现第一张图的CPU那行颜色区域都很低,而第二张图CPU那块都占满了,这表示CPU占用率高。
FPS详情
我们之前只是对哪个时间段的FPS低有了一个大致的了解,如果我们想要了解具体的情况,我们可以将鼠标浮动到Frames那一行,这样可以了解到具体的帧的FPS。
同样点击选中那一帧,还可以在下方的摘要(Summary)中查看具体的情况。
CPU工作详情
选中Main那一行,下方的摘要就会显示主线程CPU各个活动的耗时。
但是即使如此,可能您也只能知道大致是哪个阶段出了问题,比如渲染还是脚本执行时间过长。
如果想要快速定位,您可以展开Main查看具体的工作详情。
在Main那一行的展开详情中,可能会出现一些红色的三角符号或者红色区块,点击选中之后会有相应的优化提示,下方摘要也会展示出来。
比如上图中就是因为强制回流导致的性能瓶颈。
可以看一下摘要中红框中的链接,很方便地告诉了我们到底是哪段代码出了问题,点击进去:
我们可以发现是调用了offsetTop导致的回流,然后优化这部分代码即可。
至于具体的优化我们这里就不讲了,关于性能优化可以参考一下:Web Fundamentals的Performance。
关于更多性能面板的介绍可以看下:如何使用Timeline 和 Timeline事件参考。
这里说个小技巧,在Timeline上可以按Ctrl+F,然后搜索事件,这样可以在大量的事件中快速定位想找的事件。
JavaScript分析器
还是More tools中打开JavaScript Profiler面板,怎么打开这里不讲了,操作好多遍了。
然后记录下页面一段时间的js执行情况。
我们看到的上图就是记录结果,默认是分析模式是Heavy (Bottom Up)。
这个模式下可以看到哪些函数对性能影响最大并能够检查这些函数的调用路径。
分析模式有下面三种:
- Chart。显示按时间顺序排列的火焰图
- Heavy (Bottom Up)。按照函数对性能的影响列出函数,让您可以检查函数的调用路径
- Tree (Top Down)。显示调用结构的总体状况,从调用堆栈的顶端开始。
Heavy (Bottom Up)和Tree (Top Down)比较简单,这里直接略过。
Chart的火焰图如下:
火焰图越高的部分表示函数调用的堆栈越高,但是高度并不代表什么。
这样看图肯定是看不出来什么,所以我们需要选中一块区域放大,如下图:
色块越宽表示该函数的执行时间越长,而这个才表示该函数可能需要优化。
鼠标浮动到色块上可以看到函数执行的具体信息,这里只说几个重要的点:
- Name。函数的名称。
- Self time。完成函数当前的调用所需的时间,仅包含函数本身的声明,不包含函数调用的任何函数。
- Total time。完成此函数和其调用的任何函数当前的调用所需的时间。
- URL。函数在哪个脚本中,并且它的行号。
- Aggregated self time。记录中函数所有调用的总时间,不包含此函数调用的函数。
- Aggregated total time。函数所有调用的总时间,包含此函数调用的函数。
- Not optimized。如果分析器已检测出函数存在优化可能,会在此处列出。
点击相应色块可以进到具体的函数中查看。
Memory面板
Memory面板主要用来监控页面的内存使用情况,并解决一些内存泄漏或者频繁的垃圾回收等问题。
Heap snapshot(堆快照)
使用堆快照一般用来解决内存泄漏的问题。
我们在内存面板Take snapshot之后,可以看到这样一个画面:
然后我们在上方输入Detached,会筛选出下面的结果:
这里可以看看到底是哪些DOM节点没有释放。
官网文档上显示如果DOM节点没有被引用,那么应该是红色的,但是实际上不是如此。
不过这个功能还是有些用处的,选中相应的节点可以看看到底是哪些变量引用了,然后看是否能消除这些变量。
这里得注意图中的Shallow Size表示对象自身占用内存的大小,Retained Size表示通过保持对其他对象的引用隐式占用的总内存大小,而Distance是对象到GC roots(如window或者DOM树)的距离。
Allocation instrumentation on timeline(时间线上的内存分配工具)
翻译起来有点绕口,实际上就是一个用来按时间查看内存分配情况的工具。
我们直接看一下检测结果:
我们可以看到时间轴上有不少柱子,这些柱子高度会变,表示所在的那个点分配的对象大小。
我们可以看到图中我们选中的那个时间点分配的内存大概为384byte,旁边那个100B是一个参照线。
柱子的颜色代表这些对象是否被回收了,蓝色代表还存在,灰色代表被回收了。
Application面板
这个面板内容多,但是简单易懂,本来想着写点的,太简单就算了。
主要就是关于存储和缓存的。
除此之外,就是有个关于PWA的调试,这里可以参考:调试 Progressive Web App。
我对这个涉猎较少,就不班门弄斧了。
Security面板
这个面板主要是看是否https的,有用的时候是有用,没用的时候是真没用。
总结
学习Chrome开发者工具不仅能提高我们工具的使用效率,这其中涉及到的很多前端知识点也能令人眼界大开。
在阅读Chrome的开发者工具文档时有很多缺失和不同步,这是因为它在不断地演进,包括我现在提到的一些功能也许在将来有一天就消失或者增强了。
所以我觉得对于这份指南您可以当做一份索引,有所了解,但不必记住,只要在遇到问题的时候能记起来我可以用什么工具来处理就够了。
希望这篇博客能帮助到您,也希望您能对疏漏之处指正一二。