Devtool的正确食用姿势
1 前言
作为一名合格的前端,我们不可避免的需要接触到浏览器的开发者工具,也必须掌握这个工具。介于我自身的掌握水平,我将在本文对chrome devtool的选项卡Lighthouse、Sources与Elements进行讲解,同时也对比不同浏览器之间的devtool的功能差异。
2 Lighthouse
如果你对于Performance标签并不太熟悉又想优化一些网站的性能,那么我非常建议你使用Lighthouse。运行Lighthouse你可以获得页面的一些审核指标(自由选择)、得到页面加载时各个时刻的截图,同时Lighthouse还会提供如何提高特定页面加载性能的提示。
2.1 Lighthouse的使用
下图是Lighthouse的启动界面,目前在启动Lighthouse时,需要选择四个选项。分别是模式、网站会在哪个设备运行、需要测试的类别、是否包含广告插件。
Lighthouse的不同模式略有差异。我们需要了解一下一些使用场景、使用方式的差异。
- Navigation 导航模式
导航模式作为默认模式,其使用场景是首次进入页面的分析,即其指标与评分是在测试首屏渲染,无法分析页面加载后需要手动触发使用的内容。同时根据官方文档,其对于表单提交或者SPA页面转换也没有分析的能力。受益于Navigation,我们可以得到页面加载各个时刻的页面加载截图。
注意,仅该模式可以分析所有的类别和插件。点击“分析网页加载情况”,此时页面会重载,无需手动操作,等待片刻Lighthouse即会输出一份报告。
- Timespan 时间跨度模式
时间跨度模式是我最喜欢的模式,其可以测量布局变化和交互,它允许我们在一个时间范围内自由操作页面,Lighthouse会在我们结束后分析整个过程的各个指标。对于网页性能优化来讲,Timespan绝对是最佳选择(实际上,Timespan目前也确实只支持性能分析)。
使用时间跨度模式,需要在Lighthouse准备就绪后操作页面,在所有操作完毕后,点击结束时间跨度模式Lighthouse将开始审查整个操作过程,输出一份性能报告。
- Snapshot 快照
快照模式,顾名思义,快照模式下Lighthouse不会重新加载页面,它会直接分析当前页面当前状态得出各项指标。注意,快照模式下,不能分析广告和PWA。
使用快照模式的方式和导航模式类似,点击后Lighthouse会自动审查分析,不需要额外操作。
一个有趣的事情是,lighthouse可以通过nodejs的方式启动。此时虽然仍有Navigation等模式的区分,但是我们可以在启动后做一些点击、表单一系列操作。
2.2 Lighthouse的指标
我们将以Navigation模式中生成的指标作为基础讲解各个指标,其他两个模式的指标与Navigation模式中生成的指标并无太大区别,其基本逻辑都是:lighthouse提供诊断分数——提供优化建议——提供诊断结果。
2.2.1 性能Performance
在Performance报告中,其由性能分数、性能指标、优化建议、诊断结果组成。
关于性能分数的计算,也就是下图这一部分,Lighthouse官方给了一份完整的计算方式讲解,同时包含了一个在线计算器。
根据这份计算方式讲解,我们可以了解到,Lighthouse 10对下边的五个指标进行加权计算得到性能分数。这五个指标,即目前主流性能检测中常见的First Contentful Paint、Speed Index、Largest Contentful Paint、Total Blocking Time、Cumulative Layout Shift。
我想大部分前端同学或多或少都听过这些指标的大名,但是或许大部分人并不了解其中的含义,所以我们有必要进行更详细的讲解。报告中的指标部分就是具体展示了这些指标,并同时提供了原始追踪记录和资源加载树状图。其中的原始追踪记录,会导向Performance标签,我们暂不做演示。我们首先讲解五个指标的意义,再看一下树状图。
-
First Contentful Paint
FCP测量的是,用户进入到页面后浏览器呈现第一段DOM内容所需的时间,这个时间一般是秒。页面上的图像、非白色
<canvas>元素和SVG都被认为是DOM内容,而iframe里面的任何东西都不包括在内。在上边的图中,我们会发现对我这份报告来说,FCP为1s,颜色显示为黄色,这是因为Lighthouse的评分标准中,对于0-49呈现红色,50-89呈现黄色,90-100呈现绿色。而对于FCP来说,根据官方文档(2021-06-04更新),这一块的分数以1.8和3分为界限。1.8s以下为绿色,3s以上为红色。但是实测下来,1s的表现仍是黄色,对于这里存在的差异,官方文档中有提到FCP的得分计算方式是与真实网站做比较,基于HTTP Archive的数据。例如,99%中执行的站点在大约0.5秒内呈现FCP。如果我们的网站的FCP是0.5秒,则FCP得分99。
那么我们可以根据截至2023年6月1日的数据,计算得出目前的评分表(对于PC网页):
FCP time(in seconds) Color-coding 0–1.1 Green (fast) 1.1–2.1 Orange (moderate) Over 2.1 Red (slow) -
Largest Contentful Paint
LCP测量视口中最大的内容元素何时呈现到屏幕上。这个指标的意义是,最大内容元素的呈现近似于用户看到页面主要内容的时间。LCP的测量方式相比FCP更复杂,根据W3C对于LCP的测量范围定义,最大内容绘制考量的元素类型为:
W3C还提供了具体的API使用案例,Devtool中对于LCP的测量即依赖于
PerformanceObserver。<img src="large_image.jpg"> <p id='large-paragraph'>This is large body of text.</p> ... <script> const observer = new PerformanceObserver((list) => { let perfEntries = list.getEntries(); let lastEntry = perfEntries[perfEntries.length - 1]; // Process the latest candidate for largest contentful paint }); observer.observe({entryTypes: ['largest-contentful-paint']}); </script> -
Total Blocking Time
TBT代表当任务用时超过 50 毫秒时计算首次内容绘制 (FCP) 和可交互时间之间的所有时间段的总和,以毫秒表示。通过将第一次内容绘制和交互时间之间的所有长任务的阻塞部分相加来计算总和。任何执行时间超过50毫秒的任务都是长任务。50ms之后的时间量是阻塞部分。例如,如果Lighthouse检测到70ms长的任务,则阻塞部分将是20ms。
-
Cumulative Layout Shift
CLS对布局进行审查,是测量视觉稳定性的一个以用户为中心重要指标,因为该项指标有助于量化用户经历意外布局偏移的频率。所谓布局偏移,就是在交互时,页面布局的跳动。导致页面布局跳动的因素一般是图像加载未定义宽高、滚动条显隐挤压内容变化,更多可能导致布局跳动的因素,可以参考下边这份文档layout-instability。
-
Speed Index
Speed Index 表明了网页内容的可见填充速度。该速度指数的分数计算方式和FCP类似,参考了HTTP Archive。其测量方式是在页面加载过程中内容以视觉方式显示的速度。Lighthouse首先捕获浏览器中页面加载的视频,并计算帧之间的视觉进展。然后Lighthouse使用Speedline Node.js模块生成速度指数得分。
简述了这些指标,我们说说资源加载树状图。该树状图根据单个文件的大小排列与展示,方便看到是哪些资源拖累了页面加载。同时,其计算了哪些文件中的哪些部分是未使用的,帮助开发者寻找到需要精简的文件。
要注意的是,浏览器插件的代码也会影响评分。
剩下的部分中,lighthouse给出了优化建议和诊断结果,这一部分内容通过红橙绿三色表示严重程度,每一项都可以展开查看详细结果。这些优化建议根据上方的指标可以进行筛选,相当于手把手教导我们如何优化工程优化网页来提高相关指标的得分。
2.2.2 无障碍功能
对于中小型网站,可能对于无障碍功能考虑得会比较少。但是,随着互联网的发展,人们愈发考虑无障碍人群的体验了。浏览器作为一个非常核心的互联网窗口,自然不能停下脚步,lighthouse提供的无障碍功能检测一方面可以让我们具体感知到自己网页的无障碍程度,一方面也通过它提供的多条指标与指引了解浏览器的无障碍标准。
Devtool工具会检查网页的ARIA、对比度、名称和标签,帮助改善辅助技术用户的体验。从测试结果来看,lighthouse提供的检测报告总共包含44项自动检测,10项手动检查,所以我说lighthouse提供了一个很好的学习途径,54项检查我整理在下边的表格中,需要自取。
| 问题 | 说明 |
|---|---|
图片元素缺少 [alt] 属性 | 说明性元素应力求使用简短的描述性替代文字。未指定 alt 属性的装饰性元素可被忽略。 |
| 链接缺少可识别的名称 | 请确保链接文字(以及用作链接的图片替代文字)可识别、独一无二且可聚焦,这样做会提升屏幕阅读器用户的导航体验。 |
<meta name="viewport"> 元素中使用了 [user-scalable="no"],或者 [maximum-scale] 属性小于 5。 | 对于必须依靠放大屏幕才能清晰看到网页内容的弱视用户而言,停用缩放功能会给他们带来问题。 |
| 背景色和前景色没有足够高的对比度。 | 对于许多用户而言,对比度低的文字都是难以阅读或无法阅读的。 |
列表并非只包含 <li> 元素和脚本支持元素(<script> 和 <template>)。 | 屏幕阅读器会采用特定的方法来读出列表内容。确保列表结构正确有助于屏幕阅读器顺利读出相应内容。 |
列表项 (<li>) 未包含在 <ul>、<ol> 或 <menu> 父元素中。 | 屏幕阅读器要求列表项 (<li>) 必须包含在父 <ul>、<ol> 或 <menu> 中,这样才能正确读出它们。 |
文档 <body> 中没有 [aria-hidden="true"] | 在文档 <body> 上设置 aria-hidden="true" 后,辅助技术(如屏幕阅读器)的工作方式不一致。 |
[role] 具备所有必需的 [aria-*] 属性 | 一些 ARIA 角色有必需属性,这些属性向屏幕阅读器描述了相应元素的状态。 |
[role] 值有效 | ARIA 角色必须具备有效值,才能执行它们的预期无障碍功能。 |
| 按钮有可供访问的名称 | 当某个按钮没有无障碍名称时,屏幕阅读器会将它读为“按钮”,这会导致依赖屏幕阅读器的用户无法使用它 |
| 表单元素具有关联的标签 | 标签可确保辅助技术(如屏幕阅读器)正确读出表单控件。 |
文档包含 <title> 元素 | 屏幕阅读器用户可借助标题来大致了解某个页面的内容,搜索引擎用户则非常依赖标题来确定某个页面是否与其搜索相关。 |
<html> 元素包含 [lang] 属性 | 屏幕阅读器用户可借助标题来大致了解某个页面的内容,搜索引擎用户则非常依赖标题来确定某个页面是否与其搜索相关。 |
<html> 元素的 [lang] 属性具备有效值 | 指定有效的 BCP 47 语言有助于屏幕阅读器正确读出文字。 |
“[accesskey]”值是独一无二的 | 快捷键可让用户快速转到页面的某个部分。为确保正确进行导航,每个快捷键都必须是独一无二的。 |
[aria-*] 属性与其角色匹配 | 每个 ARIA“role”都支持一部分特定的“aria-*”属性。如果这些项不匹配,会导致“aria-*”属性无效。 |
button、link 和 menuitem 元素都有可供访问的名称 | 如果某个元素没有无障碍名称,屏幕阅读器会将它读为通用名称,这会导致依赖屏幕阅读器的用户无法使用它。 |
[aria-hidden="true"] 元素都不含可聚焦的下级元素 | 有一个 [aria-hidden="true"] 元素包含可聚焦的下级元素,导致这些交互式元素都无法被辅助技术(如屏幕阅读器)用户使用。 |
| ARIA 输入字段都有可供访问的名称 | 如果某个输入字段没有无障碍名称,屏幕阅读器会将它读为通用名称,这会导致依赖屏幕阅读器的用户无法使用它。 |
ARIA meter 元素都有可供访问的名称 | 如果某个输入字段没有无障碍名称,屏幕阅读器会将它读为通用名称,这会导致依赖屏幕阅读器的用户无法使用它。 |
ARIA progressbar 元素都有可供访问的名称 | 如果某个 progressbar 元素没有无障碍名称,屏幕阅读器会将它读为通用名称,这会导致依赖屏幕阅读器的用户无法使用它。 |
具有 ARIA [role]且要求子元素必须包含特定[role]的元素包含全部必需子元素。 | 一些 ARIA 父角色必须包含特定子角色,才能执行它们的预期无障碍功能。 |
[role] 包含在其必需的父元素中 | 一些 ARIA 子角色必须包含在特定的父角色中,才能正确执行它们的预期无障碍功能。 |
| ARIA 切换字段都有可供访问的名称 | 如果某个切换字段没有无障碍名称,屏幕阅读器会将它读为通用名称,这会导致依赖屏幕阅读器的用户无法使用它。 |
ARIA tooltip 元素都有可供访问的名称 | 如果某个 tooltip 元素没有无障碍名称,屏幕阅读器会将它读为通用名称,这会导致依赖屏幕阅读器的用户无法使用它。 |
ARIA treeitem 元素都有可供访问的名称 | 如果某个 treeitem 元素没有无障碍名称,屏幕阅读器会将它读为通用名称,这会导致依赖屏幕阅读器的用户无法使用它。 |
[aria-*] 属性具备有效值 | 辅助技术(如屏幕阅读器)无法解读值无效的 ARIA 属性。 |
[aria-*] 属性有效且拼写正确 | 辅助技术(如屏幕阅读器)无法解读名称无效的 ARIA 属性。 |
| 该页面包含一个标题、跳过链接或地标区域 | 添加用于绕过重复内容的方式有助于键盘用户更高效地浏览页面。 |
<dl> 只包含经过适当排序的 <dt> 和 <dd> 组及 <script>、<template> 或 <div> 元素。 | 如果未正确标记定义列表,屏幕阅读器读出的内容可能会令人困惑或不准确。 |
定义列表项已封装在 <dl> 元素中 | 定义列表项(<dt> 和 <dd>)必须封装在父 <dl> 元素中,以确保屏幕阅读器可以正确地读出它们。 |
处于活动状态的可聚焦元素的 [id] 属性都是独一无二的 | 所有可聚焦的元素都必须具有独一无二的 id,以确保能被辅助技术识别。 |
| ARIA ID 都是独一无二的 | ARIA ID 的值必须独一无二,才能防止其他实例被辅助技术忽略。 |
| 表单字段都没有多个标签 | 有多个标签的表单字段可能会被辅助技术(如屏幕阅读器)以令人困惑的方式播报出来,因为这些辅助技术可能会使用第一个标签或最后一个标签,也可能会使用所有标签。 |
<frame> 或 <iframe> 元素有标题 | 屏幕阅读器用户依靠框架标题来描述框架的内容。 |
| 标题元素按降序显示 | 未跳过任何等级且排序正确的标题会准确传达页面的语义结构,从而使得相应页面在使用辅助技术时更易于浏览和理解。 |
<input type="image"> 元素有对应的 [alt] 文字 | 将图片用作 <input> 按钮时,提供替代文字有助于屏幕阅读器用户了解该按钮的用途。 |
文档未使用 <meta http-equiv="refresh"> | 用户并不希望网页自动刷新,因为自动刷新会不断地将焦点移回到页面顶部。这可能会让用户感到沮丧或困惑。 |
<object> 元素有对应的替代文字 | 屏幕阅读器无法转换非文字内容。通过向 <object> 元素添加替代文字,可帮助屏幕阅读器将含义传达给用户。 |
所有元素的 [tabindex] 值都不大于 0 | 值大于 0 意味着明确的导航顺序。尽管这在技术上可行,但往往会让依赖辅助技术的用户感到沮丧。 |
<table> 元素中使用 [headers] 属性的单元格引用的是同一表格中的单元格。 | 屏幕阅读器提供了更便于用户浏览表格内容的功能。请确保那些使用 [headers] 属性的 <td> 单元格仅引用同一个表格中的其他单元格,这样做可提升屏幕阅读器用户的体验。 |
<th> 元素和 [role="columnheader"/"rowheader"] 的元素具备它们所描述的数据单元格。 | 屏幕阅读器提供了更便于用户浏览表格内容的功能。确保表格标头始终引用特定一组单元格可以提升屏幕阅读器用户的体验。 |
[lang] 属性的值有效 | 为元素指定有效的 BCP 47 语言有助于确保屏幕阅读器正确读出文字。 |
<video> 元素包含带 [kind="captions"] 的 <track> 元素 | 如果视频提供了字幕,失聪用户和听障用户便能更轻松地获取此视频中的信息。 |
| 页面具有逻辑选项卡顺序 | 按照视觉布局在页面中进行制表。用户无法聚焦屏幕外的元素。 |
| 交互式控件可通过键盘聚焦 | 自定义交互式控件可通过键盘聚焦,并显示聚焦指示器。 |
| 交互元素表示它们的目的和状态 | 交互式元素,如链接和按钮,应指示其状态,并与非交互式元素区分开来。 |
| 用户的焦点指向添加到页面的新内容 | 如果将新内容(如对话框)添加到页面中,则用户的注意力将指向该内容。 |
| 用户焦点不会意外地被困在某个区域 | 用户可以切换到任何控件或区域,而不会意外地捕捉到他们的焦点。 |
| 自定义控件具有关联的标签 | 自定义交互式控件具有关联的标签,由aria标签或aria labeledby提供。 |
| 自定义控件具有ARIA角色 | 自定义交互式控件具有适当的ARIA角色。 |
| 页面上的视觉顺序遵循DOM顺序 | DOM顺序与视觉顺序相匹配,改进了辅助技术的导航。 |
| 屏幕外内容对辅助技术隐藏 | 屏幕外的内容通过显示隐藏:none或aria hidden=true。 |
| 使用HTML5语义化元素用于改进导航 | <main>、<nav>等用于改进辅助技术页面的键盘导航。 |
2.2.3 最佳做法
lighthouse中有比较简单的网页最佳做法诊断功能,包含了16项诊断内容。这一块比较好理解,
| 问题 | 说明 |
|---|---|
| 注册“unload”事件监听器 | “unload”事件不会可靠地触发,而且监听该事件可能会妨碍系统实施“往返缓存”之类的浏览器优化策略。请改用“pagehide”或“visibilitychange”事件。 |
| 已检测到的 JavaScript 库 | 页面上检测到的所有前端 JavaScript 库。这里会有一个表格 |
| 请确保 CSP 能够有效地抵御 XSS 攻击 | 强有力的内容安全政策 (CSP) 可显著降低遭遇跨站脚本攻击 (XSS) 的风险。 |
| 使用 HTTPS | 所有网站都应该通过 HTTPS 来保护,即使网站不处理敏感数据,也应如此。这包括要避免使用developers.google.com/web/fundame… HTTPS 实现初始请求,但却通过 HTTP 加载某些资源)。HTTPS 可防止入侵程序篡改或被动地监听您的应用与用户之间的通信,它是 HTTP/2 和许多新的网络平台 API 的先决条件 |
| 避免在网页加载时请求地理定位权限 | 如果网站在缺少上下文的情况下请求位置信息,会导致用户不信任网站或感到困惑。建议将请求与用户操作进行绑定。 |
| 避免在网页加载时请求通知权限 | 如果网站在缺少上下文的情况下请求发送通知,会导致用户不信任网站或感到困惑。建议将请求与用户手势进行绑定。 |
| 允许用户粘贴到输入字段中 | - |
| 显示的图像宽高比正确 | 图像显示尺寸应与自然宽高比相匹配。 |
| 所提供的图片都采用了合适的分辨率 | 图片的自然尺寸应与显示屏大小及像素比成正比,这样才能令图片达到最清晰的显示效果。 |
| 页面包含 HTML DOCTYPE | 指定 DOCTYPE 会阻止浏览器切换到怪异模式。 |
| 正确地设定了字符集 | 必须声明字符编码。您可以在 HTML 的前 1024 个字节中使用 标记来声明,也可以在 HTTP 响应标头 Content-Type 中进行声明。 |
| 请勿使用已弃用的 API | 已弃用的 API 最终将从浏览器中移除。 |
| 控制台日志中未记录浏览器错误 | 控制台中记录的错误表明有未解决的问题。这些问题的起因可能是网络请求失败和其他浏览器问题。 |
| Chrome Devtools 的“Issues”面板中无任何问题 | Chrome Devtools 的“Issues”面板中记录的问题表明有未解决的问题。这些问题的起因可能是网络请求失败、安全控件不足和其他浏览器问题。如需详细了解每个问题,请打开 Chrome Devtools 的“Issues”面板。 |
| 页面包含有效的源代码映射 | 源代码映射会将缩减了大小的代码转换成原始源代码。这有助于开发者在正式版中调试。此外,Lighthouse 还能提供进一步的数据分析。建议部署源代码映射以充分利用这些好处。 |
| 已预加载使用 font-display: optional 的字体 | 请预加载 optional 字体以方便初访者使用。 |
2.2.4 SEO
我们知道,搜索引擎能过通过爬虫爬取网页信息形成,而不同网页爬取到的信息可能是不同的,这就是SEO存在的来源。lighthouse提供了15项SEO优化建议。
| 问题 | 说明 |
|---|---|
| 页面已被屏蔽,无法编入索引 | 如果搜索引擎无权抓取您的网页,则无法将它们添加到搜索结果中。(robots.txt) |
| 结构化数据有效 | 运行search.google.com/structured-… |
| 具有包含 width 或 initial-scale 的 标记 | 不仅会针对移动设备屏幕尺寸优化您的应用,还会阻止developer.chrome.com/blog/300ms-… |
| 文档包含 元素 | 屏幕阅读器用户可借助标题来大致了解某个页面的内容,搜索引擎用户则非常依赖标题来确定某个页面是否与其搜索相关。 |
| 文档有 meta 描述 | 元描述可能会被包含在搜索结果中,以简要概括网页内容。 |
| 页面返回了有效的 HTTP 状态代码 | 返回无效 HTTP 状态代码的页面可能无法被正确编入索引。 |
| 链接有描述性文字 | 描述性链接文字有助于搜索引擎理解您的内容。 |
| 链接都是可抓取的 | 搜索引擎可能会使用链接中的 href 属性来抓取网站。请确保锚元素的 href 属性链接到合适的目标网站,以便搜索引擎发现该网站上的更多网页。 |
| robots.txt 有效 | 如果 robots.txt 文件的格式不正确,抓取工具可能无法理解您希望以何种方式抓取网站内容或将其编入索引。 |
| 图片元素具备 [alt] 属性 | 说明性元素应力求使用简短的描述性替代文字。未指定 alt 属性的装饰性元素可被忽略。 |
| 文档的 hreflang 有效 | hreflang 链接用于告知搜索引擎应在特定语言或地区的搜索结果中显示哪种版本的网页。 |
| 文档中没有插件 | 搜索引擎无法将插件内容编入索引,而且许多设备都限制或不支持使用插件。 |
| 文档的 rel=canonical 有效 | 规范链接用于建议应在搜索结果中显示哪个网址。 |
| 文档所用的字体大小清晰可辨 | 12px 以下的字体过小,会导致用户无法辨认;此外,这样的字体需要移动设备访问者“张合双指进行缩放”才能阅读。请尽量让 60% 以上的页面文字不小于 12px。 |
| 点按目标的大小合适 | 交互式元素(例如按钮和链接)应足够大 (48x48px),周围有足够的空间以便用户轻松点按,且不遮挡其他元素。 |
2.2.5 PWA
渐进式Web应用是Chrome推进的离线网页应用,lighthouse会检测网页是否可以安装为PWA应用以及提供安装为PWA应用后的优化项。
我们将优化项整理出来一个表格,但是其他的部分我是建议直接看官网内容:了解如何构建优秀的渐进式 Web 应用。
| 问题 | 说明 |
|---|---|
| 无法注册用于控制网页和 start_url 的 Service Worker | Service Worker 是一项技术,可让您的应用使用很多渐进式 Web 应用功能,例如离线、添加到主屏幕和推送通知。 |
| 未针对自定义启动画面进行配置Failures: Manifest does not have name. | 选定主题的启动画面可确保用户在从主屏幕中启动您的应用时获得优质体验。 |
| 为地址栏设置主题背景颜色。 | 可以为浏览器地址栏设置与您的网站相契合的主题。 |
| 已根据视口正确设置内容尺寸 | 如果应用内容的宽度与视口的宽度不一致,该应用可能不会针对移动设备屏幕进行优化。 |
| 具有包含 width 或 initial-scale 的 标记 | 不仅会针对移动设备屏幕尺寸优化您的应用,还会阻止developer.chrome.com/blog/300ms-… |
| 清单不含可遮罩的图标 | 利用可遮盖式图标,可确保应用安装到设备上后,图片可填满整个形状轮廓,而不会出现黑边。 |
2.3 Lighthouse的其他事项
lighthouse提供了多报告、清除报告、导出打印报告等能力,方便开发者使用。
同时你会发现,我们忽略了移动设备的选择,这是因为经过测试,移动设备的选型不影响我们了解lighthouse的使用。值得关注的是,选择移动设备会有额外的优化项,请开发者们自行探索。
3 Souces源代码
来到激动人心的Souces调试工具,作为一名前端开发,一定且必须对前端代码调试工具中的王者有一个深刻的了解。
3.1 左侧面板
看到左侧选项卡,目前Devtools提供了五个选项卡。
其中的网页选项卡提供了对当前网页已加载的所有资源进行索引的功能,可以比较方便地浏览页面资源。内容脚本选项卡也提供了类似的功能,区别在于Content Script是网页的上下文运行的JS文件,可以通过该JS文件获取DOM和捕获DOM事件。如果你了解过浏览器插件的开发,会更明白两者的区别。
网页选项卡
内容脚本选项卡
文件系统选项卡类似vscode,我们可以拖拽本地的文件夹到其中,就会形成工作区。这一点和后边的替换选项卡是非常相似的,它提供一种在Devtool上修改代码同步到本地文件的能力。官方给出的场景是这样的:
- 你的桌面上有你网站的源代码。
- 你正在从源代码目录运行本地Web服务器,因此可以在访问站点
localhost:8080。 localhost:8080已经在Google Chrome中打开了,你正在使用DevTools来更改网站的CSS。
在这种情况下,可以方便地同步代码。
Overrides替换面板可以用本地的文件覆盖到网页上的文件。具体的操作流程是 :
- 在Overrides面板中选择保存到本地哪个文件夹中。此时弹出权限申请,点击允许即可。
- 在网页或内容脚本亦或者从Elements选项卡选中需要覆盖的文件,右键保存到上一步选择的文件夹中。这一步也可以通过在文件编辑区右键—保存并覆盖。
- 等待片刻,此时已经可以看到Overrides中出现被替换的文件,并且其右下角存在一个小点点代表链接成功。此时修改文件即便刷新页面也不会丢失。
最后还有一个小功能是Code Snippets,代码片段功能可以让我们更方便地编写一些小demo在浏览器上运行。再也不用在console艰难地编写代码了。
3.2 中间面板
页面中间的编辑区域的使用需要结合右方选项卡使用。主要核心区域是最左侧的行数与断点调整区,在这里单击某行可以添加一个普通断点,左侧的卡标变成蓝色证明断点打成功了。
而这只是最基本的使用,Devtool中的打断点方式并不只是以行为断点去打,而是可以细分到某行某列。我们知道,现在大部分网页会把源代码压缩成一行,如果不能如此细分,那对于线上调试非常不友好。
除此之外,通过右键的方式还可以选择添加”条件断点“,”日志点“,”不暂停点“。图中的粉色为日志点,其余两个橙色的剩下两个点。
除却最重要的左侧断点区域之外,最上方的选项卡右键后可以看到菜单,提供了一些便捷的导航、复制、标签管理等功能。
同理,在文件编辑区域右键同样可以打开菜单。值得注意的是,如果右键的文件是JS或CSS文件,可以看到来源映射选项,该选项支持我们为文件添加sourcemap文件还原源代码。
3.3 右侧面板
右侧的面版是Souces面板的核心部分,所以一一讲解。
3.3.1 监视
监视功能是我认为最好用的功能之一。我们可以在监视中输入变量名或者进行函数调用。通过”+“添加新的监视,通过刷新按钮可以重新获取当前值。通过右键则可以删除单条或所有监视。注意,像我图中正在debug一个TSX文件,显然这是经过sourcemap映射出来的源文件,但是监视时,变量名是取编译后文件中的,所以如果存在变量名重复不同域,很可能监视中并不能成功监视,这种情况建议通过代码规范规避。
3.3.2 断点
断点选项卡提供了本网页内所有断点的浏览与管理功能,并且额外提供了两个选项:遇到未捕获的异常时暂停以及遇到异常时暂停,这两个选项非常适合在bugfix时使用(心酸)。
3.3.3 作用域
再就是作用域选项卡,作用域的概念我就不过多阐述了,属于JavaScript基础知识。作用域中一般包含当前断点所在的作用域、模块作用域、脚本作用域、全局作用域这些作用域中存在的变量。
在这里可以比较方便看到当前作用域内各个变量及其值,甚至还可以通过双击修改。右键其中的变量还可以实现将其取出放置入console控制台等操作。
3.3.4 调用堆栈
调用堆栈选项卡显示了当前断点在堆栈中的位置,一般来讲我们的日常开发中不用接触到这一层,但是如果是在进行bug问题定位以及源码阅读时,堆栈中显示的每一帧就可以成为极大的助力,帮助我们更好地看懂代码的运行流。
通过右键堆栈,我们还可以复制具体的堆栈轨迹和重启堆栈帧。所谓堆栈轨迹好理解,但是重启堆栈帧并不好理解,根据谷歌出来的答案,"重启堆栈帧"(Restart Frame)是一个用于调试 JavaScript 代码的功能。当你在调试过程中遇到一个错误或者想要重新执行某个函数时,"重启堆栈帧"功能可以帮助你回溯到指定的函数调用,并重新执行该函数,以便重新跟踪代码执行流程。
具体来说,"重启堆栈帧"功能会将调试器回溯到指定函数的调用点,并重新执行该函数及其之后的代码。它的作用和使用场景如下:
- 调试错误代码:当你在调试过程中遇到一个错误,并且想要重新执行引发错误的函数,你可以使用"重启堆栈帧"来回溯到该函数的调用点,并重新执行该函数,以便重新跟踪错误产生的原因。
- 验证代码更改:当你对代码进行修改后,想要验证修改是否有效或者希望重新执行某个函数以检查修复后的行为时,"重启堆栈帧"功能可以帮助你快速回溯到修改点,并重新执行相关代码。
- 测试函数调用:在某些情况下,你可能需要多次执行某个函数以验证其行为或观察其输出。通过使用"重启堆栈帧",你可以在不重启整个调试会话的情况下多次执行特定函数,提高调试效率。
注意,"重启堆栈帧"功能仅影响当前调试会话的执行流程,并不会修改实际代码或影响应用程序的运行。它是一个有用的工具,用于在调试过程中探索和调整代码执行流程。
3.3.5 XHR/提取断点
XHR断点,顾名思义可以在发送AJAX请求时暂停代码执行。通过加号按钮可以添加网址,在发送AJAX请求时,如果网址包含指定内容则触发断点暂停。
3.3.6 DOM断点
DOM断点的使用需要搭配Elements选项卡。这里演示一下如何使用:
- 在Elements找到需要监控的元素,右键——发生中断的条件,选择自己需要的监控条件
- 观察到DOM断点中出现该断点。
- 尝试触发条件,会发现断点停在了我们修改DOM的代码处。
3.3.7 全局监听器
全局监听器指的是globalThis,即window上的监听器(不包含document哦)。提供了监听器移除,添加的监听器代码溯源这些功能。
同时,右键监听器,还可以将其设置为”被动式“,在全局监听器中,"被动式"(Passive)是一个指示选项,用于控制事件监听器的行为。当将事件监听器设置为被动式时,它表明监听器不会调用 preventDefault() 来阻止事件的默认行为。这意味着即使监听器被触发,事件的默认行为仍会继续执行。
被动式监听器的主要目的是提高滚动性能。在过去,浏览器的滚动事件监听器通常会调用 preventDefault() 来阻止滚动事件的默认行为,以实现自定义滚动行为。然而,这样做会导致浏览器在滚动期间被阻塞,从而导致滚动性能下降。
通过将滚动事件监听器设置为被动式,浏览器可以更好地优化滚动性能。当事件被触发时,浏览器可以在不受阻塞的情况下执行滚动操作,并且不会等待监听器完成。这可以显著提高滚动的平滑度和响应性。要将事件监听器设置为被动式,需要使用 addEventListener() 方法,并在 options 参数中将 passive 属性设置为 true,如下所示:
window.addEventListener('scroll', scrollHandler, { passive: true });
并非所有的事件都支持被动式监听器。只有那些不会改变元素布局或引起页面重绘的事件(如滚动、触摸滑动等)才能使用被动式监听器。对于那些需要 preventDefault() 来阻止默认行为的事件(如点击链接、提交表单等),不应将其设置为被动式。
3.3.8 事件监听器断点
事件监听器断点提供了对某类事件的断点监控功能,可以细致到某类事件的具体事件。
3.3.9 CSP违规断点
最后一项是CSP违规断点。这应该是大部分初级开发不会接触到的选项。CSP(Content Security Policy)违规断点是 Chrome DevTools 中的一种调试工具,用于在网页中检测和调试 CSP 违规情况。CSP 是一种安全策略,用于限制网页中允许加载和执行的资源,以减少恶意代码的风险。
使用 CSP 违规断点,可以暂停网页的执行,并检查哪些资源加载违反了 CSP 策略。设置 CSP 违规断点后,当网页中发生 CSP 违规时,DevTools 会在断点位置暂停,此时可以查看违规的详细信息。
CSP 违规断点的主要作用如下:
- 检测 CSP 违规:CSP 违规断点可以帮助捕获网页中的 CSP 违规情况。当网页中的资源加载违反了 CSP 策略时,DevTools 会在断点位置暂停代码执行,能够检查违规的资源和相应的策略。
- 调试 CSP 策略:通过设置 CSP 违规断点,可以分析和调试网页中的 CSP 策略。当某个资源被阻止加载或执行时,我们可以使用断点来查看导致 CSP 违规的具体策略和原因。
如要使用CSP断点,需要选择 "CSP Violations" 选项,使 DevTools 可以在网页中的 CSP 违规发生时暂停代码执行并显示相关信息。
3.3.10 顶部选项卡
顶部选项卡用于操控代码的运行,从左到右的各个选项其功能和快捷键分别是:暂停/继续(F8)、不深入函数内部并跳过下一个函数的继续下一步运行(F10),进入函数内部的继续下一步运行(F11),立即从当前函数快速跳出并运行到调用该函数位置的下一步运行(Shift+F11)以及单步调试(F9),以及最后一个选项用于暂时关闭所有断点。
4 Elements
我本来不想写Elements选项卡了的,毕竟元素选项卡作为最经典的选项卡,其功能必定应该被每一位前端熟知并使用。
但是我想并不是的,知识的诅咒决定了当我们一旦知道某种知识,就无法想象不知道这种知识时会发生什么,所以现在我只能假设在座的各位都是猴子。
那么可以从图中看到,元素标签页可以分成左右两栏,其中左侧展示了整个页面的所有DOM节点,而右侧则提供了对左侧选中DOM节点的属性查看、编辑等能力。
4.1 左侧面板
通过右键左侧面板中的DOM节点可以唤醒Element面板的高级功能。
自上而下,前五项都是对于当前网页内容的直接修改,并不值得一提。而中间的复制功能比较有意思。开发者工具除却提供复制DOM节点的完整代码外,还提供了复制outerHTML、复制selector、复制JS路径、复制样式、复制XPath、复制完整XPath等多个选项。
为方便诸位读者观看,我整理了一份表格,陈述这些复制的作用。下边以图中的DOM元素举例:
| 复制项 | 复制内容 | 作用 |
|---|---|---|
| outerHTML | ||
| 精选专栏榜 | ||
| / | ||
| selector | #juejin > div.view-container.container.index-container > main > div > div.timeline-container > div > div > div.hot-list-container.hot-list > div > div:nth-child(2) > div > div > span | 选择器,最基本的就是可以用于document.selector |
| JS路径 | document.querySelector("#juejin > div.view-container.container.index-container > main > div > div.timeline-container > div > div > div.hot-list-container.hot-list > div > div:nth-child(2) > div > div > span") | 可以在控制台直接选中该元素 |
| 样式 | -webkit-text-size-adjust: 100%; … | 复制DOM节点的CSS样式 |
| XPath | //*[@id="juejin"]/div[1]/main/div/div[2]/div/div/div[1]/div/div[2]/div/div/span | 一个基础例子,通过document.evalute选择页面元素。 |
| 完整XPath | -/html/body/div[1]/main/div/div[2]/div/div/div[1]/div/div[2]/div/div/span | - |
继续往下的几个选项中,强制修改DOM的执行状态是常用且特别好用的功能,可以让选中的DOM元素直接进入特定状态。
剩下的值得关注的选项就是最下边的“存储为全局变量”,选择该选项控制台中会自动生成一个临时变量选中该元素,方便测试。
4.2 右侧面板
Chrome的右侧面板包含了样式、计算样式、布局、事件监听器、DOM断点、DOM属性、无障碍功能这几个选项卡。
4.2.1 样式
样式选项卡一方面是提供了查看作用在DOM节点的各个样式,一方面提供了对样式修改的能力。在这些能力之余,过滤功能可以过滤需要的文件,“:hov”选项则提供了和上边强制执行状态相同的功能,“.cls”选项可以让我们方便地增删当前DOM节点的class,加号按钮则提供了直接新建一个样式类的能力。
至于小刷子……我不清楚为什么放这里,因为它可以调整是否开启夜间模式,但是却是一个全局的开关。
4.2.2 计算样式
计算样式相比样式选项卡,更多的是作为查看DOM具体样式的工具,计算样式选项卡下的样式可以分组显示,根据样式的类型(比如Layout—position)进行分类,同时,还通过图像表现了DOM元素的盒模型。
如果你在研究样式BUG,非常建议在计算样式寻找问题而不是在样式中查找。
4.2.3 布局
devtool中的布局选项,可以在不同的DOM上显示其线框表达其布局信息,可以帮助排插一些样式问题。
至于剩下几个点就不讲了,DOM断点和事件监听器和Souces源代码是有些重复的。
5 Chrome vs Safari vs FireFox vs WechatMiniProgram(Devtool)
Edge排除,原因是其内核就是Chromium,Devtool也和Chrome一样。
世间的浏览器并不止Chrome一种,这里列举了目前的浏览器三巨头以及国内较流行的微信小程序开发者工具,我们将对比它们的Devtool之间的差异。
5.1 Elements元素
#1 Chrome
Chrome Devtool作为目前最全面和强大的开发者工具,其基本上被各个前端开发视为标准开发者工具。其相比另外两者,提供了更多关于DOM属性结合JS的内容,包括事件监听器、DOM断点、属性,通过Chrome Devtool可以更方便地了解到DOM节点的状态。由于这部分内容类似于源代码中的页面,不做讲解。
#2 FireFox
Firefox的元素页面被称作”Inspector“,其提供了”Changes“,”Fonts“,”Animations“的定制化功能。
Changes选项旨在标记出开发者对页面样式等改动,会以高亮的形式显示修改的内容。
Fonts选项提供给开发者查看网页使用了哪些字体、当前选中元素字体相关属性的快捷调节与展示。
Animations选项则提供了对于当前元素及其子元素存在的CSS Animation进行追踪的功能,借助该功能,可以控制时间轴控制元素动画所处位置,观察动画状态。
除此之外,Firxfox还额外提供了界面颜色选取的取色器。
#3 Safari
相比之下,Safari浏览器的开发者工具和前两者的差异更大,相比之下,Safari的Elements界面更具有个性,比如底部常驻console控制台,比如下图中的标尺、元素打印、将元素使用默认外观、显示页面元素合成的边框、启用绘图闪烁这些功能。
除此之外,Safari浏览器在右侧也提供了字体选项卡,但是相比Firefox略单调,只有比较基础的展示功能。另外一个定制的则是”层“选项卡,层是Safari浏览的网页渲染组合机制,定位fixed、与其他符合元素重叠都会导致元素成为层。
#4 Wechat Mini Progamm
微信小程序开发者工具的开发者工具是由chrome devtool改造而来的,Elements选项卡在这里化作”WXML“选项卡。微信团队为其添加了Dataset、Component Data和Scope Data三个选项,并删除了其他选项卡,这几个选项卡和小程序的组件机制有关,会显示一些组件的属性。
5.2 Console控制台
实际测试可知,这四个开发者工具的Console控制台功能基本一致。其中Chrome浏览器看起来更专业,配置项更多:
而Firefox在保证基本功能的同时,新增了代码片段,类似于一个小型IDE,和Chrome中Souces选项卡中的代码片段类似。Firefox对人性化做得甚至比Safari更好,在Firefox的控制台中甚至可以查看完整的网络请求。
Safari的控制台功能略单薄,比如相比前两者就缺失了在控制台打印网络请求的能力。而微信小程序就不用说了,是从Chrome Devtool中照搬过来的。
5.3 Souces源代码
我们上边有详细讲过Chrome的Souces面板,所以Chrome的部分可以参考上边的段落。而Firefox浏览器的Souces面板实际称呼为”Debugger“,其功能基本和Chrome一致,只是相对来讲功能没有Chrome那么全面,除却额外提供了Outline选项卡用于得到当前文件中的函数之外,其他部分都与Chrome一致或缺失。
Safari的调试面板则更个性化,它提供的断点类型甚至比Chrome还要多,提供了微任务、requestAnimationFrame、setTimeout、setInterval等断点。至于其他功能,虽然UI相似度非常低,但是大多数功能并无差别。
微信开发者工具的表现与Chrome完全一致。
5.4 Command Menu
我们说过,Chrome是最全面最专业的浏览器。截至2023/7/6,只有Chrome提供了命令菜单的功能。在Chrome Devtool中,可以通过Ctrl+Shift+P唤起命令行工具,在其中有非常多更专业的功能。 比如,输入FPS可以找到帧数计量器,唤起后可以看到页面渲染帧率和GPU占用。
这之中还有更多宝藏功能,请诸位开发者自行探索。
5.5 整体
#1 Chrome
Chrome具有最详细的功能,就选项卡而言,Chrome的选项卡最起码有二十个,而我们常用的不过手指之数。如果我们真要讲,本文怕不是不够。
#2 Firefox
Firefox具备常用开发需要的所有功能,对样式开发有更好的支持。
#3 Safari
相比其他的主流浏览器,Safari一直是比较特立独行的,其开发者工具中提供的时间线、图形、层、审核一系列选项卡,这些功能即便是Chrome中都没有。但是由于苹果喜欢闭源的特性,Safari并没有插件能力,所以并不建议作为主力开发浏览器。
#4 Wechat Mini Progamm
小程序是类似浏览器的存在,所以我也将其提了出来。相比前三位,微信开发者工具具备比较多的定制能力,比如AppData选项卡用于获取页面中的状态、Vulnerability用于接口安全扫描、Mock选项卡提供了Mock的能力、Storage选项卡是小程序版本缓存的操作菜单
综上所述,我认为Chrome Devtools不愧为一流的开发者工具,不管你是前端小白还是资深前端开发,选择它没有错。而Firefox devtools同为老牌的开发者工具,其专业性虽然对比Chrome devtools略有不足,但是用户体验是极好的,适合前端小白使用,且Firefox提供的Fonts、Animations以及Style Editor让它在前端样式与用户体验优化上更有优势。至于Safari,Safari的闭源机制并不支持插件,像React开发时常用的插件就无法安装,所以不建议使用Safart进行开发。
6 总结
本文详细介绍了Chrome Devtool的Lighthouse和Souces两个选项卡,然后对比了三大浏览器以及微信小程序的开发者工具之间的差别。 就Chrome Devtool的选项卡介绍而言,希望大家能从中有所收获。而就开发者工具比较而言,是希望读者可以从中了解到各个开发者工具之间的差距。