baixiaoji / blog

writting & thinking
3 stars 0 forks source link

那些你不需要知道的Chrome DevTool ——使用技巧篇 #21

Open baixiaoji opened 5 years ago

baixiaoji commented 5 years ago

使用技巧

前提

默认读者已经具备了基本的Chrome DevTools 的知识,即了解Chrome开发者工具中每一个面板的基本用法

如果尚未了解,请自助查看同事写的基本介绍

当然,你也可以选择继续往下读。

快捷键

常用几个面板的快捷键如下:

  1. Elements Panel Command+Option+C (Mac) 或 Control+Shift+C (Windows, Linux, Chrome OS).

  2. Console Panel

    Command+Option+J (Mac) 或 Control+Shift+J (Windows, Linux, Chrome OS)

  3. 打开上一次停留的面板

    Command+Option+I (Mac) 或 Control+Shift+I(Windows, Linux, Chrome OS)

  4. 调用命令菜单栏

    Command+Shift+P(Mac)或Control+Shift+P(Windows, Linux, Chrome OS)

对于剩下 DevTools 所有的快捷键,请自行查看

Elements Panel

  1. 如何快速定位一个元素,并出现在视窗中?

    可以再面板中进行搜索Command+F,元素主面板会唤起一个搜索条,搜索条中可以输入 CSS 选择器进行过滤,找到对应元素后,右键点击scroll to view,便可以再视窗中查看到该元素。

  2. 如何定位元素上绑定的事件?

    定位到了目标元素,然后元素面板中的幅面版切换至 Event Listeners,点开事件查看函数配置,选中 handler 右键点击 Show Function DefinitionDevTools会自动跳转Source面板对应函数申明的地方。

  3. 如何监听一个DOM节点变化,是由那部分的JavaScript脚本控制的?

    在 Elements Panel 中选中目标的元素节点,然后右键查看 Break on ,查看不同的监听方式

    • Subtree modifications

      当选中节点的子节点发生变化(添加、移除、内容改变)都会触发,但是子节点属性变化以及选中节点任何变化都不会触发。

    • Atrribute modifications

      当选中节点属性变化(添加、移除、属性值变更)都会触发。

    • node removal

      当选中节点被移除时候触发。

  4. 如何页面的accessibility?从元素是否正确标记角度。

    点击Elements Panel 右侧的 Accessibility Tab,你可以查看整个页面中的Accessibility Tree,该 Tree 是DOM tree 的子集,对应节点是由对屏幕阅读器(screen reader)有关和有用的展示内容。

    可以查看每个节点的ARIA Attributes,该属性是确保屏幕阅读器(screen reader)如何从Accessibility Tree以合适的方式展示页面内容。

    为什么要提高页面的accessibility,这项性能呢?

    Web Accessibility is a way to make everyone including the disabled to have access to the web and internet in whole.

    Web accessibility means that people with disabilities can use the Web

    from Why Web Accessibility Is Important and How You Can Accomplish It

    就是为了让每一个人都能获得访问网站的权利。

    那如何审查自己的网站accessibility的状况呢?

    1. 可以安装axe查看进行审查,该插件还会给出对应的解决方案,以及可以帮助你快速定位问题元素在 Elements Panel 的位置
    2. 使用 Audits Panel 只勾选 Accessibility 选项,然后进行审查,会有对应的报告给出然后结合经验进行修复。
  5. 如何查看页面中 CSS 和 JavaScript 使用情况?

    解释「使用情况」,最理想的情况页面中使用到的 CSS 和 JavaScript 每一行都被页面使用到,但保不齐开发途中我们忘记剔除无用的代码?

    使用「快捷键」中调用命令菜单栏的命令,输入「show coverage」,便可以查看 Coverage 面板。点击面板中的刷新按钮,最后便可以得到页面中 CSS 和 JavaScript 使用情况。注:此时的表示的使用率情况是页面加载的使用率。如果想获得更全的使用率情况请点击Recording 按钮进行操作。

    双击点击任意 CSS 和 JavaScript 脚本,会自动调整到自动格式化好的 Sources Panel 中左侧会出现红绿标记,前者表示该行在页面中尚未使用,后者便是改行在页面中被使用。

  6. 如何展开所有的元素节点 ?

    选中父级节点,右键选中「Expand recursively」,Elements Panel 会将所有子节点展开,方便导航。当然对应的快捷键是 Option + click(Mac) 或 control + alt + click (Windows, Linux, Chrome OS)

Console Panel

首先 console 面板大家主要工作都是在这边查看更多代码中的日记,而console下有许多好用的API,这些 API 可以帮助你在诸多的 log 中以不同形式的方式查看,但这里边步一一赘述API了,自助查看官网

感兴趣的可以查看一篇文章:Getting creative with the Console API! 中文翻译

但是笔者钟爱time/timelog/timeEnd,这些 API 可以帮助你的代码快速粗糙的性能测试。

  1. 如何从不同类型的 log 中过滤如何自定义条件的log ?

    存在历史遗留问题的项目中,会在 console 面板看到各处(代码中/浏览器)留下的 log 。为了过滤出自己想看到的log,你可以根据console panel 中的 Filter 进行过滤。

    Filter 会有一些智能的提示关键词:

    • url: 查看对应脚本的log或是不同网址或是插件中的log。
    • source: 可以根据产生log的来源来过滤。
    • context: 可以根据不同的上下文,因为如果内嵌 <iframe>的时候会产生新的上下文。

    Filter 同样支持正则表达式进行过滤,如果想同时支持多个条件,用空格隔开。

    当然如果仅仅是为了查看一条指定的log,同样可以使用搜索,快捷键就是和你想的一样。

  2. 如何在 Console Panel 监听元素事件呢?

    我们可以使用\$0-\$4表示我们之前在 Elements Panel 中选中过的倒数四个元素。然后我们想要监听对应的元素的事件时,我们可以使用使用控制台提供的工具API ——monitorEvents(<DOM_NODE>, <Event_TYPE>)。然后当被监听元素触发对应事件的时候,控制台会打印对应的Event对象出来。

  3. 如何在其他面板中,调起另一个Console Panel?

    在Chrome DevTool中存在一个 drawer 的Tips,该面板中同样存在一个Console Panel,只要在开发者工具开启的时候,按ESC便可唤起,这样方便后续的调试。

  4. 如何复制变量到粘贴板中?

    Console 工具API 同样提供了一个copy(anything),因为我们之后每一个变量我们只要选中右键都可有一个「Store as global variable」的功能,先存在 Console Panel中,然后可以使用该方法将对应的变量复制到粘贴板中。因为很多的时候同样的接口在不同场景返回不同的数据,首先我们需要一份原始数据,通过这样的方法生成一份mock数据,然后进行修改调试。当然有时候我们仅仅想获取这个对应所有的key值或是value值时,可以配合keys(object)values(object)

  5. 如何通过Console关联到Element Panel中的DOM节点或对应的函数?

    Console 工具API 同样提供了一个inspect(<DOM_NPDE>/function)。输入对应的类型,DevTool会自动帮你定位到对应面板的对应位置。

    如果是定位DOM节点的时候,配合$或是$$使用,它俩分别是document.querySelector()document.querySelectorAll()的缩写。

    如果是定位函数时,可以使用getEventListeners(<DOM_NODE>)获取对对应的函数,然后通过该方法找到对应的函数定位。

    当然有时候,一不小心早按了回车以及「Store as global variable」不想输入那么长的变量名,则可以使用工具API中的$_代替。

    当然你也可以通过这样的方式进行定位到对应函数。

    如何你想查看更多的控制台提供的工具API,请查看

Network Panel

其实这个是工作中最常用的Panel,我们经常在这里看各样的数据。

  1. 如何查看各种请求之间的依赖关系?

    其实答案已经在我们眼前,但是我们很少关注这一点。在Network中有一列叫Initiator,而这一列展示的信息就是请求之间相互依赖的关系。

    当然你同样可以按住shfit,然后鼠标hover在每一个请求的Name这一列,你可会发现有些请求会被高亮成绿色,有些高亮成红色。而绿色就是该请求的initiator,而红色就是该请求附属的后续请求。

  2. 如何过滤出满足你预想的请求?

    其实我们都知道每一个Panel中都有一个Filter的输出框这个交互,但是我们最多写写正则匹配匹配就好了,但是往往没有尝试一些开发者工具根据所有请求归类了许多的特殊字段给我们使用。

    比如说,前不久在优化系统的时候,有一个系统中是否存在尚未压缩的资源。

    当然我们可以选择把所有请求的Size这一列一个个看过来,上面展示的压缩过后的大小,下面灰色展示为压缩前的大小,当两个数字一致时则正面资源尚未压缩。

    我们知道如果一个资源压缩过,请求对应的响应头会存在一个Content-Encoding字段。然后我们能不能根据每个请求的响应头进行搜索呢?答案是显而易见的,我们可以在 Filter 中根据has-response-header:Content-Encoding这样的条件,过滤出响应头含有Content-Encoding的响应头,然后取反便可以满足需求了。

    如果你知道更多Chrome帮我们归类好的过滤条件,请查看官网

  3. 如何屏蔽暂时无用请求?

    开发阶段存在一对多的情况下,但是同时要上线,所以前端很容易出现开发中看到许多的干扰请求,如404之类的。

    这时候你可以选中的对应的请求,右键选中「Block request url」,然后刷新页面继续在当前环境开发了。

    但是请记得在切换环境的时候,请将之前屏蔽的接口继续开启。这时候你需要使用唤起命令行菜单栏的快捷键,然后输入「show request blocking」,就可以再当前面板进行管理了。

  4. 如何评价这个接口性能?

    通常情况下,前端去评价一个接口的性能更多是由该接口返回数据时长来判断,而由此产生的问题就是如何查看接口的对应的时间呢?

    在Network Panel 中有名为「Waterfall」的一列,你可以在这里查看每一个接口什么时候开始请求,什么时候完成请求的,以及中途的信息,如下图所示:

    我们可以看到浏览器将整个接口请求到响应分为几个阶段。理解每个接口的含义是什么会帮助我们更好的评估这个接口的性能如何。

    • Queueing

      浏览器将请求都存在发送请求队列中,发生请求如下:

      • 前者发送的请求优先级较高
      • 对于当前源(origin)已经建立了6个TCP链接,限制了后续请求(仅适用于HTTP/1.0和HTTP/1.1)
      • 浏览器在从磁盘缓存中发配空间
    • Stalled

      请求可能因为Queueing中描述的任何原因进而搁置

    • DNS Lookup

      浏览器正在解析请求的IP地址

    • Proxy negotitation

      浏览器正在与代理服务器协商请求

    • Request sent

      正在发送请求

    • ServiceWorker Preparation

      浏览器正在启动 service worker

    • Request to ServiceWorker

      请求正在发送给 service worker

    • Waiting (TTFB)

      浏览器正在等待响应的第一个字节

      TTFB是Time To First Byte的缩写

      This timing includes 1 round trip of latency and the time the server took to prepare the response.

      这个时长包括1个往返的延迟和服务器准备响应所用的时间

    • Content Download

      浏览器正在接收响应

    • Receiving Push

      浏览器接受这个响应的数据,是由HTTP/2服务器推送而来

    • Reading Push

      浏览器正在读取以前接收到的本地数据

    以上是基本的概念,我们通常看到的浏览器Timing下分类的维度是这样的:

    当然你想找一些例子,看看对应分析一下请求的性能可以查看,以及对应的阶段出现问题的解决思路,请查看

Sources Panel

考验工程师debug能力了。

  1. 如何 breakpoint 任意请求?

    在上图中,我们可以看到有一处「XHR/fetch Breakpoints」功能栏。这里就可以添加我们需要中断的请求,设置的过滤请求条件可以根据请求URL上是否含有特定的字符串。

  2. 如何 breakpoint 任意代码任意环境的报错?

    因为我司主要的技术栈是 Vue,而自己维护的项目中有个别组件写法是Vue.extend为主,导致后续会出现异常,但控制台并不会输出,所以增添了部分定位问题的困难度。

    而 Chrome DevTool 提供了一个炒鸡炒鸡好用的功能,就是「 Pause on exceptions 」,只要已开启这个功能。代码中出现任何报错,他都会暂停到对应的错误那里,以及会在对应输出栏中显示错误的原因,帮助我们进行推理。

    一个用来就用学习其他Debug技巧的功能。

  3. 如何在debugger中做到TimeTravel?

    在断点期间,我们都是一个阶段一个阶段的排查对应位置的代码段。偶尔会发生进入下一个阶段的代码段的时候,突然意识到上一阶段的代码段存在部分问题,这时候往往我们都是默默走一遍全流程,感觉 DevTool 并没有提供我们一个良好的功能进行TimeTravel。

    直到我发现了Call Stack这一功能栏,这一栏中展示就是代码段执行上下文环境。而DevTool提供了一个重新回到上个函数执行的功能,就是「Restart Frame」。

  4. 如何成为一个issue提问好手?

    一直很好奇别人填写 issue 的时候,那么整齐又齐全的 Call Stack 是怎么来的。难不成是在底层函数打印一个console.trace()吗?想想这样的做法也太蛮烦了,每一次都要打印一次。

    想想 Call Stack 应该也会提供这样的功能,然后进行右键,果不其然看到了「Copy Stack Trace」的功能,点击立即复制到粘贴板中。

  5. 如何减少底层依赖库的干扰?

    有没有遇到打断点,打着打着就打到依赖的底层依赖库中了。极少可能性问题出现在底层依赖库,这时候我们想屏蔽后续断点今日这个底层依赖库?

    我们可以找到对应的底层依赖脚本文件,然后在内容区域右键会出现一个「Blackbox Script」的功能,然后从此断点不会进入到这个底层依赖脚本了。就像这样:

  6. 如何判断页面依赖 JavaScript 到什么程度?

    如果相差自己页面如果没有 JavaScript 的情况,你可以调用命令行然后输入「Disable JavaScript」便可关闭页面执行JavaScript,然后刷新页面查看吧。重新恢复的话,只要输入「Enable JavaScript」。