[译] 使用 Chrome DevTools 优化网站速度

作者 | Kayce Basques
来源 | developers.google.com
https://developers.google.cn/web/tools/chrome-devtools/speed/get-started

目标

本教程教您如何使用Chrome DevTools,以便找到让网站加载速度更快的方法。
继续阅读或者可以观看本教程的视频版本:

前提条件

• 您应该具有基本的Web开发经验,类似于 Introduction to Web Development class 中讲授的内容。
• 您无需了解任何有关加载性能的知识。您将在本教程中了解它!

介绍

下面这只猫叫Tony,在猫圈非常有名。他建立了一个网站,以便粉丝们可以了解他最喜欢的食物。他的歌迷喜欢这个网站,但是 Tony 一直抱怨网站加载缓慢。Tony 现在向你求助,以帮助他提升网站加载速度。

Step 1:审计网站

每当您想打算提高站点的加载性能时,都应该从审计开始。审计具有2个重要作用:
• 它为您创建了一个基准,以衡量后续的改进。
• 它为您提供了可行的提示,说明哪些更改将产生最大的影响。

设置

首先,我们需要设置站点,以便以后可以对其进行更改:

• 转到 chrome://version
查看您使用的Chrome版本。本教程是基于 Chrome 68。如果您使用的是早期版本或更高版本,那么某些功能可能看起来有所不同或不可用。不过您应该仍然能够完成本教程,只需记住您的UI看上去可能与屏幕截图有所不同。
• 打开该站点的源代码 https://glitch.com/edit/#!/tony。 这个选项卡我们称为编辑器选项卡。


• 点击 tony,显示菜单

• 单击 Remix This
。项目的名称从tony更改为一些随机生成的名称。您现在拥有了自己的可编辑代码副本。稍后,您将修改这些代码。

• 单击 Show Live
。这个 deom 将在新选项卡中打开。此选项卡为 demo 选项卡。这个网址可能需要加载一段时间。

• 按下 Command + Option + J(Mac)
或者  Control + Shift + J(Windows,Linux,Chrome)
。Chrome DevTools 随 demo 一起打开。

在本教程中的其余屏幕截图,DevTools 将显示为单独的窗口。可以通过按 Command + Shift + P(Mac)
或  Control + Shift + P(Windows,Linux,Chrome OS)
打开命令菜单,键入  Undock
,然后选择  Undock into separate window
来执行此操作。

建立基准

基准记录是在进行任何性能改进之前网站的运行情况。

• 单击 Audits
选项卡。它可能隐藏在“更多面板”按钮后面。该面板上有一个 Lighthouse。


• 将您的审计配置设置与上图中的设置进行匹配。以下是不同选项的说明:

○ **Device. **设置为 **Mobile** 会更改用户代理字符串并模拟移动视口。设置为 **Desktop **可以禁用 **Mobile** 的功能。
○ **Audits. **禁用一个类别可防止 Audits 面板运行这些审计,并将这些审计项从报告中排除。禁用类别会稍微加快审计过程。
○ **Throttling. **设置为 **Simulated Fast 3G,4x CPU Slowdown **可以模拟在移动设备上浏览页面的典型条件。之所以称为“模拟”,是因为 Audits 面板在审计过程中实际上并未节流。相反,它只是推断在移动条件下页面加载所需的时间。另一方面,**Applied** **Fast 3G,4x CPU Slowdown** 设置实际上会限制您的CPU和网络,需要权衡较长的审计过程。
○ **Clear Storage.** 启用此复选框会在每次审计之前清除与该页面关联的所有存储。如果要审计首次访问者如何体验您的网站,请保留此设置。当您需要重复访问体验时,请禁用此设置。

• 单击 Run Audits
。10到30秒后,Audits 面板将向您显示该站点的性能报告。

处理报告的错误

如果您在 Audits 面板报告中遇到错误,请尝试从 incognito window 运行 demo 选项卡,而不打开其他选项卡。这样可以确保您在干净状态下运行Chrome。特别是 Chrome 扩展程序经常会干扰审计过程。

理解你的报告

报告顶部的数字是该网站的总体效果得分。稍后,当您对代码进行更改时,您会看到这个数字增加了。分数越高表示性能越好。

Metrics 部分提供了站点性能的定量度量。每个指标表示性能的不同方面。例如, First Contentful Paint 
会告诉您什么时候第一次将内容绘制到屏幕上,这是用户感知页面加载的重要时刻,而  Time To Interactive
则标记了页面看起来已经准备好用户交互的时间。

将鼠标悬停在指标上以查看其描述,然后单击 Learn More
以阅读有关该指标的文档。

Metrics下方是屏幕截图的集合,这些截图显示了页面加载时的外观。

Opportunities部分提供了有关如何改善此特定页面的加载性能的特定提示。


单击 opportunity 以了解更多信息。

单击 Learn More
以查看有关 opportunity 为何如此重要的文档,以及有关如何解决的具体建议。

Diagnostics部分提供了有关影响页面加载时间的因素的更多信息。

Passed Audits部分显示该站点的正常工作的部分。单击以展开该部分。

Step 2: 实战

审计报告的 Opportunities
部分为您提供有关如何改善页面性能的提示。在本节中,我们将采纳这些建议来修改代码,并在每次更改后审核站点,以衡量它如何影响站点速度。

启用文本压缩

报告说,启用文本压缩是提高页面性能的主要方法之一。
文本压缩是指在通过网络发送文本文件之前,减小或压缩文本文件的大小。有点类似于在通过电子邮件发送文件夹时,先将其压缩以减小其大小。
在启用压缩之前,您可以通过以下两种方法手动检查文本资源是否已压缩。

• 单击 Network
选项卡。

• 单击 Use Large Request Rows
。网络请求表中的行的高度会增加。

• 如果在网络请求表中没有看到 Size
列,请右键单击表头,然后选择  Size

每个 Size
单元格显示两个值。上面的值是下载资源的大小。下面的是未压缩资源的大小。如果两个值相同,则在通过网络发送资源时不会对其进行压缩。例如,在上图中,bundle.js 的上下的值均为1.4 MB。
您还可以通过检查资源的HTTP标头来检查压缩情况:
• 单击bundle.js。

• 单击 Header
选项卡。

• 在 Response Header
中搜索  content-encoding
头。您应该看不到,这意味着  bundle.js
没有被压缩。压缩资源后,此标头通常设置为  gzip
,  deflate
或  br
。有关这些值的说明,请参考这里。
解释得差不多了。下面来做些修改!通过添加几行代码来启用文本压缩:
• 在编辑器选项卡中,单击server.js。

• 将以下代码添加到 server.js
。确保将  app.use(compression())
放在  app.use(express.static('build'))
之前。

...
const fs = require('fs');
const compression = require('compression');
app.use(compression());
app.use(express.static('build'));
...

注意:通常,您必须通过 npm i -S compression
之类的方式安装压缩软件包,但这里我们预先处理了。

等待 Glitch 部署站点的新版本。您会在 Logs and Show
旁边看到精美的动画,这意味着该站点正在重建和重新部署。当您再次看到  Show Live
时,表示更改已部署完成。


使用我们先前学习的工作流程来手动检查压缩是否正常运行:

• 返回 demo 标签并重新加载页面。现在, Size
列应为文本资源(例如bundle.js)显示2个不同的值。在下图中,bundle.js的上方的值  261 KB
是通过网络发送的文件的大小,而下面的值  1.4 MB
是未压缩的文件的大小。

bundle.js
的  Response Header
部分现在应包含一个  content-encoding
报头。


再次审计页面以衡量文本压缩对页面的负载性能有什么样的影响:

• 单击 Audits
选项卡。

• 单击 Perform an audit

• 保持与以前相同的设置。

• 单击 Run audit


oo!看起嗯,看起来有些进步。网站的整体效果得分应该有所提高,这意味着该网站的运行速度越来越快。

现实世界中的文本压缩

实际上,大多数服务器确实有简单的程序,可以启用压缩功能!只需搜索如何配置用于压缩文本的任何服务器即可。

调整图像大小

在新的报告中,提示正确调整图像大小也是一个改进点。
调整图像大小可通过减小图像文件大小来帮助加快加载时间。如果您的用户正在500像素宽的移动设备屏幕上查看图像,那么发送1500像素宽的图像确实没有意义。理想情况下,最多只能发送500像素宽的图像。

• 在报告中,单击 Properly size images
以查看应调整图像的大小。看起来所有 4 张图片都超出了需求。

• 返回编辑器选项卡,打开 src/model.js

• 将 const dir = 'big'
替换为  const dir ='small'
。此目录包含已调整大小的相同图像的副本。
• 再次审计页面以查看此更改如何影响加载性能。

看起来变化对整体性能得分的影响很小。但是,分数没有清楚显示的一件事是您为用户节省了多少网络数据。旧照片的总大小约为 5.3M
,而现在只有  0.18M

现实世界中调整图像大小

对于小型应用程序,执行这样的一次性大小调整可能就足够了。但是对于大型应用程序,这显然不可扩展的。以下是在大型应用中管理图像的一些策略:
• 在构建过程中调整图像大小。
• 在构建过程中为每个图像创建多个尺寸,然后在代码中使用 srcset。在运行时,浏览器会选择最适合其运行设备的尺寸。请参阅 Relative-sized imaged。
• 使用图像CDN,该CDN可让您在请求图像时动态调整其大小。
• 至少要优化每个图像。这通常可以节省大量流量。优化是指通过特殊程序运行图像时,该程序可以减小图像文件的大小。有关更多提示,请参见 Essential Image Optimization。

消除渲染阻塞资源

在最新的报告中,提示可以尝试消除渲染阻塞资源。
阻塞渲染的资源是外部JavaScript或CSS文件,浏览器在显示页面之前必须下载,解析和执行这些文件。目标是仅运行正确显示页面所需的核心CSS和JavaScript代码。
第一个任务是找到不需要在页面加载时执行的代码。

• 单击 Eliminate render-blocking resource
以查看存在阻塞的资源:  lodash.js
和  jquery.js

• 按 Command + Shift + P(Mac)
或  Control + Shift + P(Windows,Linux,Chrome OS)
打开“命令”菜单,键入 Coverage,然后选择  Show Coverage

• 单击 Reload
。Coverage选项卡概述了页面加载时正在执行  bundle.js
,  jquery.js
和  lodash.js
中的多少代码。图32表示jQuery和Lodash文件中未使用的代码分别约为76%和30%。

• 单击jquery.js行。DevTools在 Source
面板中打开文件。如果一行代码旁边有绿色的条,则表示该代码行已执行。红色条表示未执行,并且绝对不需要在页面加载时使用。


• 滚动浏览一下jQuery代码。一些被“执行”的行实际上只是注释。通过剥离注释的minifier运行此代码是减小此文件大小的另一种方法。

简而言之,当您使用自己的代码时, Coverage
选项卡可以帮助您逐行分析代码,并且仅交付页面加载所需的代码。

加载页面是否需要jquery.js和lodash.js文件呢? Request Blocking
选项卡可以显示资源不可用时发生的情况。

• 单击 Network
选项卡。

• 按 Command + Shift + P(Mac)
或  Control + Shift + P(Windows,Linux,Chrome OS)
再次打开“命令”菜单。

• 开始键入 blocking
,然后选择  Show Request Blocking

• 单击 Add Pattern
,键入  /libs/*
,然后按  Enter
确认。

○ 重新加载页面。jQuery和Lodash请求为红色,表示它们已被阻止。该页面仍处于加载状态并且是交互式的,因此看起来这些资源都是不需要的!

• 点击 Remove all patterns
,以删除  /libs/*
阻塞模式

通常, Request Blocking
选项卡可用于在任何给定资源不可用时模拟页面的行为。
现在,从代码中删除对这些文件的引用,然后再次审计页面:

• 返回编辑器选项卡,打开 template.html

• 删除

• 等待站点重建并重新部署。
• 在 Audits 面板再次审计页面。您的总体分数应该会再次提高。

在实际项目中优化关键渲染路径

关键渲染路径是指加载页面所需的代码。通常,您可以通过仅在页面加载过程中交付关键代码,然后延迟加载其他所有内容来加快页面加载速度。
• 您不太可能找到可以完全删除的脚本,但是您经常会发现在页面加载期间许多脚本并不是必须的,而可以异步请求这些脚本。请参阅使用异步或延迟。
• 如果您使用的是框架,请检查其是否有生产模式。此模式可以使用诸如 tree shaking 之类的功能,以消除阻塞关键渲染的不必要代码。

减少主线程工作

最新报告在 Opportunities
部分显示了一些潜在的优化项,但是如果您在  Diagnostics
部分中查看,则似乎最大的瓶颈是过多的主线程活动。
主线程是浏览器处理显示页面所需的大部分工作的地方,例如解析和执行HTML,CSS和JavaScript。

目的是使用 Performance
面板来分析页面加载时主线程正在执行的工作,并找到延迟或删除不必要工作的方法。

• 单击 Performance
选项卡。

• 单击 Capture Settings

• 将 Network
设置为  Slow 3G
,将  CPU
设置为  6x slowdown
。与笔记本电脑或台式机相比,移动设备通常有更多的硬件限制,因此这些设置使您可以像使用功能较弱的设备一样体验页面加载。

• 单击 Reload
。DevTools 将重新加载页面,然后生成可视化效果,以显示该页面的全部加载。该可视化页面将称为  trace


trace 从左到右按时间顺序显示活动。顶部的 FPS,CPU 和 NET 图表概述了每秒的帧数,CPU 活动和网络活动。在下图中看到的黄色条形表示 CPU 完全忙于脚本活动。这表明您可以通过减少JavaScript工作来加快页面加载速度。


深入 trace 以找到减少JavaScript工作的方法:

• 单击 User Timing
部分以将其展开。基于似乎有很多 User Timing 来自 React 的事实,似乎Tony的应用程序正在使用React的开发模式。切换到React的生产模式可能会带来一些性能优化。

• 再次单击 User Timing
以折叠该部分。

• 浏览 Main
部分。本节从左到右显示了主线程活动的时间顺序日志。y轴(从上到下)显示事件发生的原因。例如,在下图中,  Evaluate Script
事件导致执行  (anonymous)
函数,这导致执行  ../rbd/pnpm-volume/...
,导致  __webpack__require__
执行,依此类推。

向下滚动到 Main
部分的底部。使用框架时,大多数活动是由框架引起的,通常这是您无法控制的。您的应用程序引起的活动通常在底部。在此应用程序中,似乎一个名为App的函数大量调用了  mineBitcoin
函数。听起来Tony可能正在使用他的粉丝的设备来挖掘加密货币...


注意:尽管框架进行的调用通常不受您的控制,但有时您可能会以导致框架无法高效运行的方式来构造应用。重组应用程序以有效使用框架是减少主线程工作的一种方法。但是,这需要深入了解框架的工作原理,以及可以在自己的代码中进行哪些更改才能更有效地使用框架。

• 展开 Bottom-Up
部分。此标签可细分哪些活动占用最多的时间。如果在  Bottom-Up 
部分没有看到任何内容,请单击  Main
部分的标签。  Bottom-Up 
仅显示有关当前所选活动或活动组的信息。例如,如果您单击mineBitcoin活动之一,则  Bottom-Up 
将仅显示该活动的信息。

Self Time栏显示您直接在每个活动中花费了多少时间。例如,上图显示,大约57%的主线程时间花费在  mineBitcoin
函数上。
是时候看看使用生产模式并减少JavaScript活动是否会加快页面加载速度了。从生产模式开始:

• 在编辑器选项卡中,打开 webpack.config.js

• 将 "mode": "development"
更改为  "mode": "production"

• 等待新的构建部署。
• 再次审核页面。

通过删除对 mineBitcoin
的调用来减少JavaScript活动:

• 在编辑器选项卡中,打开 src/App.jsx

• 在构造函数中注释掉对 this.mineBitcoin(1500)
的调用。
• 等待新的构建部署。
• 再次审计页面。


看起来最后一次更改导致性能大幅提升!

注意:本节对 Performance
面板进行了相当简短的介绍。请参阅性能分析参考,以了解有关如何使用它来分析页面性能的更多信息。

在实际项目中减少主线程工作

通常, Performance
面板是了解您的网站在加载时会执行的活动并找到删除不必要活动的方法的最常用方法。

如果您希望使用一种更像 console.log()
的方法,可以使用  User Timing API
随意标记应用程序生命周期的某些阶段,以跟踪每个阶段花费的时间。

来自 Tony 的特别感谢

Tony的粉丝喜欢这个网站的运行速度,Tony非常感谢您的帮助。单击下面的“接收礼物”,以从Tony那里收到特别礼物。

总结

• 每当您着手优化站点的加载性能时,请始终从审计开始。审计将建立基准,并为您提供有关改进的提示。
• 一步一步地更改,并在每次更改后审计页面,以查看该孤立的更改如何影响性能。


就差您点一下了 :point_down::point_down::point_down: