Lighthouse:优化网站速度

Kayce Basques
Kayce Basques
Sofia Emelianova
Sofia Emelianova

教程的目标

本教程介绍了如何使用 Chrome 开发者工具提升网站加载速度。

请继续阅读或观看本教程的视频版本:

前提条件

您应该具备基本的 Web 开发经验,这与“Web 开发简介”课程中所学的内容类似。

您无需了解有关加载性能的任何信息。

简介

我是 Tony。托尼在猫咪界非常有名。他开设了一个网站,以便粉丝了解他最喜欢的食物。他的粉丝非常喜欢这个网站,但 Tony 一直抱怨网站加载速度太慢。Tony 请您帮他提高网站速度。

Tony the cat。

第 1 步:审核网站

每当您着手提高网站的加载性能时,一定要从审核开始。此项审核具有两项重要职能:

  • 它为您���量后续更改创建基准
  • 它为您提供了富有实用价值的提示,让您了解哪些更改会带来最佳效果。

设置

首先,您需要为 Tony 的网站设置新的工作环境,以便稍后可以对其进行更改:

  1. 在 Glitch 上混剪网站项目。新项目会在一个标签页中打开。 此标签页称为“编辑器”标签页。

    点击“混剪”后打开的原始来源和“编辑器”标签页。

    项目名称从 tony 更改为一个随机生成的名称。现在,您便拥有了自己的可修改代码副本。稍后,您将更改此代码。

  2. 在编辑器标签页的底部,依次点击预览 > 在新窗口中预览。该演示将在新标签页中打开。该标签页称为演示标签页。网站可能需要一段时间才能加载完毕。

    “演示”标签页。

  3. 在演示旁边打开开发者工具

    开发者工具和演示。

建立基准

基线是在您进行任何性能改进之前网站性能的记录。

  1. 打开 Lighthouse 面板。它可能隐藏在 更多面板后面。

    Lighthouse 面板。

  2. 将您的 Lighthouse 报告配置设置与屏幕截图上的相应设置相匹配。以下是对不同选项的说明:

    • check_box 清空存储空间。选中此复选框将在每次审核之前清除与该网页关联的所有存储空间。如果您想审核初访者在您网站上的体验,请将此设置保持开启状态。如果您想提供重复访问体验,请停用此设置。
    • check_box 启用 JS 采样。此选项在默认情况下处于停用状态。开启该功能后,系统会将详细的 JavaScript 调用堆栈添加到性能跟踪记录中,但可能会减慢报告生成速度。生成 Lighthouse 报告后,您可以在 more_vert Tools menu > View Unthrottled Trace 下找到轨迹。 未进行 JS 采样(左)和进行 JS 采样(右)的性能跟踪记录。
    • 模拟节流(默认) 。此选项可模拟在移动设备上浏览的典型条件。之所以称之为“模拟”,是因为 Lighthouse 在审核过程中实际上不会进行限制。而是推断网页在移动设备上的加载时间。另一方面,DevTools 节流(高级)设置实际上会限制 CPU 和网络,但需要较长的审核过程。
    • 模式 > 导航(默认)。此模式将分析单个网页加载,而我们在本教程中需要此模式来分析。如需了解详情,请参阅三种模式
    • 设备 > 移动设备。移动设备选项会更改用户代理字符串并模拟移动设备视口。“桌面设备”选项几乎会停用移动设备更改。
    • 类别 > check_box 效果。启用单一类别后,Lighthouse 仅会生成包含一组相应审核的报告。如果您想查看其他类别提供的建议类型,可以将其保持启用状态。停用不相关的类别可稍微加快审核过程。
  3. 点击分析网页加载。10 到 30 秒后,Lighthouse 面板会显示该网站的效果报告。

    关于网站性能的 Lighthouse 报告。

处理报告错误

如果您在 Lighthouse 报告中遇到错误,请尝试在无痕式窗口(不打开其他标签页)中运行演示标签页。这可确保您从干净的状态运行 Chrome。特别是 Chrome 扩展程序 可能会干扰审核过程

包含错误的报告。

解读报告

报告顶部的数字是网站的总体效果得分。稍后,当您更改代码时,您应该会看到此数字增加。得分越高,效果越好。

总体表现得分。

指标

向下滚动到指标部分,然后点击展开视图。如需阅读有关某个指标的文档,请点击了解详情...

“指标”部分。

此部分提供了对网站性能的量化衡量标准。 每个指标都可以让您深入了解效果的一个不同方面。例如,First Contentful Paint(首次内容绘制)会告知您首次将内容绘制到屏幕上的时间,这是用户感知到的网页加载量的一个重要里程碑,而 Time To Interactive 则标记了网页显示得足以处理用户互动的时间点。

屏幕截图

接下来是一组屏幕截图,向您展示网页在加载后的显示效果。

屏幕截图:网页在加载时的外观。

商机

接下来是优化部分,其中提供了有关如何提高此特定网页的加载���能的具体提示。

“优化”部分。

点击相应优化建议即可了解详情。

详细了解文本压缩机会。

点击了解详情...可查看有关优化建议的重要性的文档,以及有关如何修正此问题的具体建议。

诊断

诊断部分会详细介绍造成网页加载时间的因素。

“诊断”部分。

已通过的审核

已通过的审核部分会显示网站正常运行的内容。点击以展开该部分。

“已通过的审核”部分。

第 2 步:实验

Lighthouse 报告的优化部分提供了有关如何提高网页性能的提示。在本部分中,您将对代码库实施建议的更改,并在每次更改后审核网站,以衡量这些更改对网站速度的影响。

启用文本压缩

您的报告显示,启用文本压缩是提升网页性能的首要机会之一。

文本压缩是指先缩减或压缩文本文件的大小,然后再通过网络发送。就像在通过电子邮件发送文件夹之前压缩文件夹的大小一样。

在启用压缩之前,您可以通过以下几种方式手动检查文本资源是否已压缩。

打开 Network 面板,然后勾选 Settings > Use large request rows

“Network”面板中的“Size”列,显示了大型请求行。

每个 Size 单元格会显示两个值。顶层值是下载资源的大小。底部值是未压缩资源的大小。如果这两个值相同,则表示通过网络发送资源时未进行压缩。在此示例中,bundle.js 的顶部值和底部值均为 1.4 MB

您还可以通过检查资源的 HTTP 标头来检查是否进行了压缩:

  1. 点击 bundle.js 并打开标头标签页。

    “Headers”标签页。

  2. 响应标头部分搜索 content-encoding 标头。您应该不会看到一个这样的过滤器,这意味着 bundle.js 未经过压缩。压缩资源时,此标头通常设置为 gzipdeflatebr。有关这些值的说明,请参阅指令

说明已经够多了。该进行一些更改了!添加几行代码即可启用文本压缩:

  1. 在编辑器标签页中,打开 server.js 并添加以下两行(突出显示的内容):

    ...
    const fs = require('fs');
    const compression = require('compression');
    
    app.use(compression());
    app.use(express.static('build'));
    ...
    
  2. 请务必将 app.use(compression()) 放在 app.use(express.static('build')) 之前。

    修改 server.js。

  3. 等待 Glitch 部署网站的新版本。左下角的快乐表情符号表示部署成功。

使用您之前学习的工作流手动检查压缩是否正常:

  1. 返回演示标签页并重新加载页面。

    对于 bundle.js 等文本资源,Size 列现在应显示两个不同的值。bundle.js 的最大 269 KB 值是通过网络发送的文件大小,最低的 1.4 MB 值是未压缩的文件大小。

    “大小”列现在针对文本资源显示两个不同的值。

  2. bundle.js响应标头部分现在应包含 content-encoding: gzip 标头。

    响应标头部分现在包含一个内容编码标头。

再次在页面上运行 Lighthouse 报告,以衡量文本压缩对页面加载性能的影响:

  1. 打开 Lighthouse 面板,然后点击顶部操作栏上的 添加 Perform an audit...

    执行审核按钮。

  2. 保持设置不变,然后点击分析网页加载

    启用文本压缩后的 Lighthouse 报告。

棒极了!这看起来像是进展。您的总体效果得分应该会有所提高,这表示网站速度变快了。

文本压缩实际应用

大多数服务器确实采用类似这样的简单修复方法来启用压缩!只需搜索如何配置用于压缩文本的服务器即可。

调整图片大小

您的新报告指出,适当调整图片大小是另一个重大机会。

调整图片大小可通过缩减图片文件大小来帮助缩短加载时间。如果您的用户在宽度为 500 像���的移动设备屏幕上查看您的图片,那么发送宽度为 1500 像素的图片实际上毫无意义。理想情况下,您最多可发送一张宽度为 500 像素的图片。

  1. 在您的报告中,点击适当调整图片大小,查看应调整哪些图片的大小。似乎所有 4 张图片都超过了必要的大小。

    关于“适当尺寸的图片”优化建议的详细信息

  2. 返回编辑器标签页,打开 src/model.js

  3. const dir = 'big' ��换为 const dir = 'small'。此目录包含已调整大小的相同图片的副本。

  4. 请再次审核该网页,看看此更改对加载性能有何影响。

    调整图片大小后的 Lighthouse 报告。

这项更改似乎对整体表现得分只有很小的影响。但是,该分数并不能明确表明为用户节省了多少网络数据流量。旧照片的总大小约为 6.1 MB,而现在只有 633 kB 左右。您可以在网络面板底部的状态栏中对此进行检查。

调整图片大小前后传输的数据量。

在现实环境中调整图片大小

对于小型应用,像这样一次性调整大小可能就足够了。但对于大型应用,这显然无法扩缩以下是在大型应用中管理图片的一些策略:

  • 在构建流程中调整图片大小。
  • 在构建流程中为每个映像创建多个尺寸,然后在代码中使用 srcset。在运行时,浏览器负责选择最适合运行它的设备的大小。请参阅相对大小的图像
  • 使用图片 CDN,以便在您请求图片时动态调整图片大小。
  • 至少,优化每张图片。这通常能够节省大量费用。优化是指通过能够减小图片文件大小的特殊程序运行图片。如需更多提示,请参阅基本映像优化

消除阻塞渲染的资源

您的最新报告显示,移除阻塞渲染的资源现在是最大的机会。

阻塞渲染的资源是外部 JavaScript 或 CSS 文件,浏览器必须先下载、解析和执行该文件,然后才能显示网页。目标是仅运行正确显示网页所需的核心 CSS 和 JavaScript 代码。

然后,第一个任务是查找不需要在网页加载时执行的代码。

  1. 点击消除阻塞渲染的资源,查看阻塞以下的资源:lodash.jsjquery.js

    详细了解“减少阻塞渲染的资源”机会。

  2. 根据您使用的操作系统,按以下方式打开命令菜单

    • 在 Mac 上,按 Command + Shift + P
    • 在 Windows、Linux 或 ChromeOS 上,按 Ctrl + Shift + P
  3. 开始输入 Coverage,然后选择显示覆盖率

    从 Lighthouse 面板打开命令菜单。

    覆盖率标签页会在抽屉式导航栏中打开。

    “覆盖率”标签页。

  4. 点击刷新 重新加载。通过“覆盖率”标签页,您可以大致了解网页加载时 bundle.jsjquery.jslodash.js 中有多少代码正在执行。

    “索引涵盖范围”报告。

    此屏幕截图显示,分别大约有 74% 和 30% 的 jQuery 和 Lodash 文件未被使用。

  5. 点击 jquery.js 行。DevTools 会在 Sources 面板中打开该文件。如果一行代码旁边有绿色条,则表示已执行该代码。如果代码行旁边有一个红色条,则表示该代码未执行,在网页加载时肯定不需要。

    在“Sources”面板中查看 jQuery 文件。

  6. 滚动浏览一下 jQuery 代码。某些“执行”的行实际上只是注释。另一种减小此文件大小的方法是,通过可去除注释的压缩工具运行此代码。

简而言之,当您使用自己的代码时,覆盖率标签页可以帮助您逐行分析代码,并仅交��网页加载所需的代码。

加载页面是否甚至需要 jquery.jslodash.js 文件?请求屏蔽标签页可以显示在资源不可用时会发生什么情况。

  1. 点击网络标签页,然后再次打开命令菜单
  2. 开始输入 blocking,然后选择显示请求屏蔽。系统会打开请求屏蔽标签页。

    “请求屏蔽”标签页。

  3. 点击 添加 Add Pattern,在文本框中输入 /libs/*,然后按 Enter 键进行确认。

    添加一种模式,以阻止对“libs”目录的任何请求。

  4. 重新加载页面。 jQuery 和 Lodash 请求显示为红色,表示它们已被阻止。该页面仍会加载并且具有互动性,因此您似乎根本不需要这些资源!

    “网络”面板显示请求已被屏蔽。

  5. 点击 移除。 移除所有格式以删除 /libs/* 屏蔽格式。

通常,请求屏蔽标签页有助于模拟任意给定资源不可用时网页的行为。

现在,从代码中移除对这些文件的引用,并再次审核网页:

  1. 返回编辑器标签页,打开 template.html
  2. 删除相应的 <script> 标记:

    <head>
        ...
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <script src="/libs/lodash.js"></script>
        <script src="/libs/jquery.js"></script>
        <title>Tony's Favorite Foods</title>
    </head>
    
  3. 等待网站重建并重新部署。

  4. 请从 Lighthouse 面板再次审核此页面。您的总体得分应该会再次提高。

    移除阻塞渲染的资源后的 Lighthouse 报告。

在现实世界中优化关键渲染路径

“关键呈现路径”是指加载网页所需的代码。一般来说,您可以在网页加载期间仅传送关键代码,然后延迟加载其他内容,从而加快网页加载速度。

  • 您不太可能能够找到可以直接移除的脚本,但经常会发现,许多脚本在网页加载期间不需要请求,而是可以异步请求。请参阅使用 async 或 defer
  • 如果您使用的是框架,请检查它是否有生产模式。此模式可能会使用摇树优化等功能,以消除会阻塞关键渲染的不必要代码。

减少主线程工作

您的最新报告显示 Opportunity 部分可以略微节省一些费用,但如果您向下滚动到 Diagnostics 部分,最大的瓶颈似乎是主线程活动过多。

主线程是浏览器执行显示网页所需的大部分工作(例如解析和执行 HTML、CSS 和 JavaScript)的地方。

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

  1. 依次打开 Performance > 设置。 Capture Settings,然后将 Network 设置为 Slow 3G,将 CPU 设置为 6x speeddown

    “性能”面板中的设置 CPU 和网络节流

    与笔记本电脑或台式机相比,移动设备通常具有更强的硬件限制,因此这些设置可让您体验网页加载时设备性能欠佳的情况。

  2. 点击刷新 重新加载。 DevTools 会重新加载页面,然后直观呈现其加载页面所需的所有操作。我们将这种可视化方式称为“跟踪记录”。trace

    “性能”面板的网页加载跟踪记录。

轨迹按时间顺序从左到右显示活动。顶部的 FPS、CPU 和 NET 图表可让您大致了解每秒帧数、CPU 活动和网络活动。

跟踪记录的“概览”部分。

您在概览部分看到的黄色墙表示 CPU 完全忙于执行脚本活动。 这表明您可以通过减少 JavaScript 工作量来加快网页加载速度。

调查跟踪,以找到减少 JavaScript 工作量的方法:

  1. 点击计时部分将其展开。

    “计时”部分。

    React 提供了许多 User Timing 衡量指标,Tony 的应用似乎使用的是 React 的开发模式。切换到 React 的生产模式可能会轻松获得一些性能提升。

  2. 再次点击计时可收起该部分。

  3. 浏览主要部分。此部分按时间顺序显示主线程活动的日志(从左到右)。y 轴(从上到下)显示事件发生的原因。

    “主要”部分。

    在此示例中,Evaluate Script 事件导致 (anonymous) 函数执行,进而导致执行 __webpack__require__,进而执行 ./src/index.jsx,依此类推。

  4. 向下滚动到 Main 部分的底部。使用框架时,大部分顶层 activity 都是由框架引起的,而这通常不受您的控制。应用产生的 activity 通常位于底部。

    mineBitcoin 活动。

    在此应用中,名为 App 的函数似乎导致对 mineBitcoin 函数的大量调用。看来 Tony 可能在使用粉丝的设备进行加密货币挖矿...

  5. 打开底部的 Bottom-Up 标签页。此标签页细分了哪些活动耗时最长。如果 Bottom-Up 部分中未显示任何内容,请点击 Main 部分的标签。

    “Bottom-Up”标签页。

    Bottom-Up 部分仅显示您当前所选的任何活动或活动组的信息。例如,如果您点击了一个 mineBitcoin activity, Bottom-Up 部分将仅显示该 activity 的信息。

    自用时间列会显示直接在每项活动中花费的时间。在本例中,大约 82% 的主线程时间花在了 mineBitcoin 函数上。

现在来看看使用生产模式和减少 JavaScript 活动能否加快页面加载速度。从生产模式开始:

  1. 在编辑器标签页中,打开 webpack.config.js
  2. "mode":"development" 更改为 "mode":"production"
  3. 等待新构建部署完成。
  4. 再次审核该网页。

    将 Webpack 配置为使用生产模式后的 Lighthouse 报告。

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

  1. 在编辑器标签页中,打开 src/App.jsx
  2. 注释掉 constructor 中对 this.mineBitcoin(1500) 的调用。
  3. 等待新构建部署完成。
  4. 再次审核该网页。

移除不必要的 JavaScript 工作后的 Lighthouse 报告。

与往常一样,您仍需进行一些调整,例如减少 Largest Contentful PaintCumulative Layout Shift 指标。

在现实世界中减少主线程工作

一般来说,通过查看 Performance 面板,您可以了解网站在加载时执行了哪些活动,并找到移除不必要的活动的方法。

如果您更喜���更接近于 console.log() 的方法,可以使用 User Timing API 随意标记应用生命周期的某些阶段,以便跟踪这些阶段中每个阶段所用的时间。

摘要

  • 每当您着手优化网站的加载性能时,一定要从审核开始。此项审核确立了基准,并为您提供有关如何改进的提示。
  • 一次进行一项更改,并在每次更改后审核页面,以了解孤立的更改对性能有何影响。

后续步骤

对您自己的网站进行审核!如果您在解读报告或寻找提升加载性能的方法方面需要帮助,请查看向开发者工具社区获取帮助的所有方式:

  • developer.chrome.com 代码库中提交有关此文档的错误。
  • Chromium Bugs 中提交有关开发者工具的错误报告。
  • 讨论邮寄名单中的功能和变更。请不要使用邮寄名单来咨询支持问题。请改用 Stack Overflow。
  • Stack Overflow 上获取有关如何使用开发者工具的常规帮助。若要提交 bug 请求,请一律使用 Chromium bug。
  • 请发送电子邮件至 @ChromeDevTools 与我们联系。