轻松提升网站性能 - 2018 年 Google I/O 大会版

在 Google I/O 2018 大会上,我们汇总了各种工具、库和优化技术,以便更轻松地提升 Web 性能。在这里,我们使用 The Oodles Theater 应用来解释这些概念。我们还讨论了预测性加载实验和新的 Guess.js 计划。

Ewa Gasperowicz

在过去一年中,我们一直忙于研究如何让 Web 变得更快、更高效。这催生了新的工具、方法和库,我们希望在本文中与您分享。在第一部分中,我们将向您展示我们在开发 Oodles Theater 应用时在实践中使用的一些优化技术。在第二部分中,我们将讨论我们在预测性加载和新的 Guess.js 计划方面的实验。

对性能的需求

互联网每年都在变得越来越沉重。如果我们查看网络状态,就会发现移动设备上的中位网页大小约为 1.5MB,其中大部分是 JavaScript 和图片。

网站规模不断扩大,再加上网络延迟、CPU 限制、渲染阻塞模式或多余的第三方代码等其他因素,导致性能问题变得复杂。

大多数用户都将速度视为用户体验需求层级中的最顶层。这并不奇怪,因为在网页加载完成之前,您无法执行太多操作。你无法从页面中获取价值,也无法欣赏其美感。

用户体验层次结构金字塔
图 1. 速度对用户有多重要?(速度至关重要,第 3 卷)

我们知道,性能对用户来说至关重要,但如何找到优化的切入点却像是一个秘密。幸运的是,有一些工具可以为您提供帮助。

Lighthouse - 性能工作流的基础

Lighthouse 是 Chrome 开发者工具的一部分,可让您对网站进行审核,并为您提供有关如何改进网站的提示。

我们最近推出了一系列新的性能审核,这些审核在日常开发工作流中非常有用。

新增 Lighthouse 审核
图 2. 新的 Lighthouse 审核

我们通过一个实际示例来探索如何利用这些功能:Oodles Theater 应用。这是一个小型演示 Web 应用,您可以在其中试玩一些我们最喜欢的互动式 Google 涂鸦,甚至可以玩一两款游戏。

在构建应用时,我们希望确保其性能尽可能出色。优化的起点是 Lighthouse 报告。

Oodles 应用的 Lighthouse 报告
图 3. Oodles 应用的 Lighthouse 报告

从 Lighthouse 报告来看,我们应用的初始性能非常糟糕。 在 3G 网络上,用户需要等待 15 秒才能看到首次有效渲染,或才能与应用互动。Lighthouse 突出显示了我们网站的大量问题,总体性能得分 23 正好反映了这一点。

该页面大小约为 3.4MB,我们迫切需要进行瘦身。

这引发了我们的第一个性能挑战:找到可以轻松移除且不影响整体体验的内容。

效果优化机会

移除不必要的资源

有一些明显可以安全移除的内容:空格和注释。

缩减大小带来的收益
图 4. 缩减 JavaScript 和 CSS 的大小并将其压缩

Lighthouse 会在“未缩减的 CSS 和 JavaScript”审核中突出显示此优化机会。我们使用 webpack 进行构建,因此为了缩减大小,我们只需使用 Uglify JS 插件。

缩减大小是一项常见任务,因此您应该能够找到适用于您所使用的任何构建流程的现成解决方案。

该领域的另一项实用审核是启用文本压缩。没有理由发送未压缩的文件,而且现在大多数 CDN 都支持开箱即用。

我们使用 Firebase Hosting 托管代码,Firebase 默认启用 gzip,因此,只需将代码托管在合理的 CDN 上,我们就能免费获得该功能。

虽然 gzip 是一种非常流行的压缩方式,但 Zopfli 和 Brotli 等其他机制也越来越受欢迎。Brotli 在大多数浏览器中都受支持,您可以使用二进制文件预压缩素材资源,然后再将其发送到服务器。

采用高效的缓存政策

我们的下一步是确保在不必要的情况下不重复发送资源。

Lighthouse 中的低效缓存政策审核帮助我们注意到,我们可以优化缓存策略,以实现这一目标。通过在服务器中设置 max-age 过期标头,我们确保用户在重复访问时可以重复使用之前下载的资源。

理想情况下,您应该尽可能多地缓存资源,尽可能长地缓存资源,并提供验证令牌,以便高效地重新验证已更新的资源。

移除未使用的代码

到目前为止,我们已经移除了不必要下载中显而易见的部分,但那些不那么明显的部分呢?例如,未使用的代码。

开发者工具中的代码覆盖率
图 5. 检查代码覆盖率

有时,我们在应用中添加的代码并非真正必要。如果您开发应用的时间较长,团队或依赖项发生变化,有时就会留下孤立库。这正是我们遇到的情况。

一开始,我们使用 Material Components 库来快速制作应用原型。 后来,我们改用了更具自定义风格的外观和风格,完全忘记了那个库。 幸运的是,代码覆盖率检查帮助我们在 bundle 中重新发现了它。

您可以在开发者工具中查看代码覆盖率统计信息,包括应用的运行时和加载时。您可以在底部屏幕截图中看到两条大红条纹 - 我们有超过 95% 的 CSS 未使用,还有大量 JavaScript。

Lighthouse 还在未使用的 CSS 规则审核中发现了此问题。它显示了超过 400kb 的潜在节省空间。因此,我们回到代码中,移除了该库的 JavaScript 和 CSS 部分。

如果去掉 MVC 适配器,样式大小会降至 10KB
图 6. 如果我们放弃 MVC 适配器,样式大小会降至 10KB!

这使我们的 CSS 软件包减少了 20 倍,对于一个只有两行代码的小型提交来说,这已经非常不错了。

当然,这提高了我们的性能得分,Time to Interactive 也得到了很大改善。

不过,面对此类变化,仅检查指标和得分是不够的。 移除实际代码并非毫无风险,因此您应始终注意潜在的回归问题。

我们的代码有 95% 未使用,但仍有 5% 的代码在某处使用。显然,我们的一个组件仍在使用该库中的样式,即涂鸦滑块中的小箭头。不过,由于它非常小,我们可以直接手动将这些样式重新整合到按钮中。

按钮因缺少库而损坏
图 7. 一个组件仍在使用已移除的库

因此,如果您移除代码,请务必建立适当的测试工作流程,以帮助您防范潜在的视觉回归。

避免网络负载过大

我们知道,大型资源可能会减慢网页加载速度。它们可能会让用户破费,还可能对用户的流量套餐产生重大影响,因此务必要注意这一点。

Lighthouse 能够通过庞大的网络载荷审核检测到我们的某些网络载荷存在问题。

检测到巨大的网络载荷
图 8. 检测巨大的网络载荷

在这里,我们看到有超过 3MB 的代码被传输下来,这相当多,尤其是在移动设备上。

在此列表的最顶部,Lighthouse 突出显示了我们有一个 JavaScript 供应商软件包,其中包含 2MB 的未压缩代码。这也是 webpack 强调的一个问题。

俗话说:最快的请求就是未发出的请求。

理想情况下,您应该衡量向用户提供的每项资源的价值,衡量这些资源的性能,并决定是否值得在初始体验中实际提供这些资源。因为有时这些资源可以延迟加载、延迟加载或在空闲时间处理。

在我们的案例中,由于我们要处理大量 JavaScript 软件包,因此我们很幸运,因为 JavaScript 社区拥有丰富的 JavaScript 软件包审核工具。

JavaScript 软件包审核
图 9. JavaScript 软件包审核

我们首先使用了 webpack bundle analyzer,它告诉我们,我们包含了一个名为 unicode 的依赖项,该依赖项包含 1.6 MB 的已解析 JavaScript,因此数量相当多。

然后,我们转到编辑器,使用 Visual Code 的 Import Cost 插件,直观地查看了我们导入的每个模块的成本。这样,我们就能发现哪个组件包含引用此模块的代码。

然后,我们改用另一个工具 BundlePhobia。借助此工具,您可以输入任何 NPM 软件包的名称,并实际查看其缩减大小和经过 gzip 压缩后的大小。我们找到了一个不错的替代方案,可以替代我们正在使用的 slug 模块,该模块只有 2.2kb,因此我们进行了切换。

这对我们的效果产生了重大影响。通过这项更改以及发现其他缩减 JavaScript 软件包大小的机会,我们节省了 2.1 MB 的代码。

如果考虑到这些 bundle 经过 gzip 压缩和缩减大小后的体积,我们发现整体性能提升了 65%。 我们发现,这个过程非常值得一试。

因此,一般来说,请尽量避免在网站和应用中进行不必要的下载。 盘点素材资源并衡量其对效果的影响,可以带来显著成效,因此请务必定期审核素材资源。

通过代码拆分缩短 JavaScript 启动时间

虽然大型网络载荷会对应用产生重大影响,但还有另一个因素也会产生重大影响,那就是 JavaScript。

JavaScript 是您最昂贵的资源。 在移动设备上,如果您发送大型 JavaScript 软件包,可能会延迟用户与界面组件互动的时间。这意味着,他们可能会点按界面,但实际上不会发生任何有意义的操作。因此,我们必须了解 JavaScript 为什么会产生如此高的开销。

这就是浏览器处理 JavaScript 的方式。

JavaScript 处理
图 10. JavaScript 处理

首先,我们必须下载该脚本,然后由 JavaScript 引擎解析、编译并执行该代码。

现在,这些阶段在高端设备(如台式机或笔记本电脑,甚至高端手机)上不会花费太多时间。但在中端手机上,此过程可能需要 5 到 10 倍的时间。这会延迟互动,因此我们必须尽量缩减这部分时间。

为了帮助您发现应用中的这些问题,我们在 Lighthouse 中引入了新的 JavaScript 启动时间审核。

JavaScript 启动时间
图 11. JavaScript 启动时间审核

以 Oodle 应用为例,它告诉我们,JavaScript 启动耗时 1.8 秒。当时的情况是,我们将所有路由和组件静态导入到一个庞大的 JavaScript 软件包中。

解决此问题的一种方法是使用代码拆分。

代码拆分就像披萨

代码拆分就是这样一个概念:与其给用户一整张披萨那么多的 JavaScript,不如在他们需要时一次只给他们一片。

代码拆分可以在路由级或组件级应用。它可与 React 和 React Loadable、Vue.js、Angular、Polymer、Preact 以及多个其他库完美搭配。

我们将代码拆分纳入应用中,从静态导入切换到动态导入,这样我们就可以根据需要异步延迟加载代码。

使用动态导入进行代码拆分
图 13. 使用动态导入进行代码拆分

这不仅缩减了 bundle 的大小,还缩短了 JavaScript 启动时间。将启动时间缩短至 0.78 秒,使应用速度提升了 56%。

一般来说,如果您要构建 JavaScript 密集型体验,请务必仅向用户发送他们需要的代码。

利用代码拆分等概念,探索摇树优化等思路,并查看 webpack-libs-optimizations 代码库,了解如何缩减库大小(如果您恰好在使用 webpack)。

优化图像

图片加载性能笑话

在 Oodle 应用中,我们使用了大量图片。遗憾的是,Lighthouse 对此的热情远不如我们。事实上,我们在所有三项与图片相关的审核中都失败了。

我们忘记了优化图片,没有正确调整图片大小,而且我们还可以通过使用其他图片格式获得一些收益。

图片审核
图 14. Lighthouse 图片审核

我们首先优化了图片。

对于一次性优化,您可以使用 ImageOptim 或 XNConvert 等可视化工具。

更自动化的方法是使用 imagemin 等库在构建流程中添加图片优化步骤。

这样,您就可以确保日后添加的图片会自动得到优化。 某些 CDN(例如 Akamai)或第三方解决方案(例如 Cloudinary、Fastly 或 Uploadcare)可为您提供全面的图片优化解决方案,因此您也可以直接在这些服务上托管图片。

如果您因费用或延迟问题而不想这样做,Thumbor 或 Imageflow 等项目提供了自托管替代方案。

优化前后
图 15. 优化前后

我们的背景 PNG 在 webpack 中被标记为大文件,这很正常。在将其正确调整为视口大小并通过 ImageOptim 运行后,文件大小降至 100kb,这是可以接受的。

对网站上的多张图片重复此操作后,我们显著降低了整体页面重量。

为动画内容使用正确的格式

GIF 的开销可能非常大。令人惊讶的是,GIF 格式最初并非用作动画平台。因此,切换到更合适的视频格式可为您节省大量文件大小。

在 Oodle 应用中,我们使用 GIF 作为首页上的介绍序列。根据 Lighthouse 的分析, 如果改用更高效的视频格式, 我们可以节省超过 7MB 的空间。我们的片段大约有 7.3MB,对于任何合理的网站来说都太大了,因此我们将其转换为具有两个源文件的视频元素 - MP4 和 WebM,以获得更广泛的浏览器支持。

将 GIF 动画替换为视频
图 16. 将 GIF 动画替换为视频

我们使用 FFmpeg 工具将 GIF 动画转换为 mp4 文件。 WebM 格式可为您节省更多空间,ImageOptim API 可以为您执行此类转换。

ffmpeg -i animation.gif -b:v 0 -crf 40 -vf scale=600:-1 video.mp4

通过此次转换,我们成功节省了 80% 以上的总体权重。这使我们的应用大小降至大约 1MB。

不过,1MB 的资源通过网络传输仍然很大,尤其是对于带宽受限的用户。幸运的是,我们可以使用 Effective Type API 了解他们使用的是低带宽,并为他们提供更小的 JPEG。

此接口使用有效往返时间和下行值来估算用户使用的网络类型。它只会返回一个字符串:slow 2G、2G、3G 或 4G。因此,根据此值,如果用户使用的是 4G 以下的网络,我们可以将视频元素替换为图片。

if (navigator.connection.effectiveType) { ... }

这确实会稍微影响体验,但至少网站在慢速连接下仍可使用。

延迟加载屏幕外图片

轮播界面、滑块或超长网页通常会加载图片,即使用户无法立即在网页上看到这些图片。

Lighthouse 会在屏幕外图片审核中标记此行为,您也可以在开发者工具的“网络”面板中自行查看。如果您看到大量图片传入,但页面上只有少数图片可见,则意味着您可能需要考虑改为延迟加载这些图片。

浏览器本身尚不支持延迟加载,因此我们必须使用 JavaScript 来添加此功能。我们使用 Lazysizes 库为 Oodle 封面添加了延迟加载行为。

<!-- Import library -->
import lazysizes from 'lazysizes'  <!-- or -->
<script src="lazysizes.min.js"></script>

<!-- Use it -->

<img data-src="image.jpg" class="lazyload"/>
<img class="lazyload"
    data-sizes="auto"
    data-src="image2.jpg"
    data-srcset="image1.jpg 300w,
    image2.jpg 600w,
    image3.jpg 900w"/>

Lazysizes 非常智能,因为它不仅会跟踪元素的可见性变化,还会主动预提取视图附近的元素,以提供最佳用户体验。 它还提供 IntersectionObserver 的可选集成,可为您提供非常高效的可见性查找。

做出此更改后,我们的图片会按需提取。如果您想深入了解该主题,请访问 images.guide,这是一个非常实用且全面的资源。

帮助浏览器尽早提供关键资源

并非通过网络传输到浏览器的每个字节都具有相同的重要性,浏览器也知道这一点。许多浏览器都有启发式算法来决定应首先提取哪些内容。因此,它们有时会在提取图片或脚本之前提取 CSS。

作为网页作者,我们可以告知浏览器哪些内容对我们来说非常重要,这可能会很有用。值得庆幸的是,在过去几年中,浏览器供应商一直在添加许多功能来帮助我们实现这一目标,例如 link rel=preconnect、preload 或 prefetch 等资源提示。

这些功能被引入 Web 平台后,有助于浏览器在适当的时间提取适当的内容,并且比使用脚本完成的一些基于逻辑的自定义加载方法更高效。

我们来看看 Lighthouse 实际上是如何引导我们有效使用其中一些功能的。

Lighthouse 建议我们首先避免多次往返任何源站,因为这会产生高昂的成本。

避免多次往返于任何源站,从而降低成本
图 17. 避免多次往返任何源站,从而降低成本

在 Oodle 应用中,我们实际上大量使用了 Google Fonts。每当您将 Google Fonts 样式表放入页面时,它都会连接到两个子网域。Lighthouse 告诉我们,如果我们能够预热该连接,则初始连接时间最多可节省 300 毫秒。

利用 link rel preconnect,我们可以有效掩盖连接延迟。

尤其是对于 Google Fonts 这样的服务,我们的字体 CSS 托管在 googleapis.com 上,而字体资源托管在 Gstatic 上,这可能会产生非常大的影响。因此,我们应用了这项优化,并缩短了几百毫秒。

Lighthouse 接下来建议我们预加载关键请求。

预加载关键请求
图 18. 预加载关键请求

<link rel=preload> 非常强大,它会通知浏览器当前导航需要某个资源,并尝试让浏览器尽快提取该资源。

现在,Lighthouse 告诉我们,我们应该去预加载关键网页字体资源,因为我们正在加载两种网页字体。

预加载网页字体如下所示:指定 rel=preload,传入 as 以及字体类型,然后指定要加载的字体类型,例如 woff2。

这可能会对您的网页产生非常明显的影响。

预加载资源的影响
图 19. 预加载资源的影响

通常,如果不使用 link rel preload,而网页字体恰好对您的网页至关重要,浏览器必须先获取 HTML,再解析 CSS,然后在更晚的时候,最终去获取网页字体。

使用 link rel preload 后,浏览器一解析完 HTML,就可以更早地开始提取这些网页字体。在我们的应用中,这能够将使用 Web 字体呈现文本所需的时间缩短一秒。

现在,如果您要尝试使用 Google Fonts 预加载字体,情况就没那么简单了,有一个陷阱。

我们在样式表中为字体指定的 Google Fonts 网址恰好是字体团队会定期更新的内容。这些网址可能会过期,或定期更新,因此,如果您想完全控制字体加载体验,我们建议您自行托管网页字体。这非常棒,因为您可以访问 link rel preload 等内容。

在我们的案例中,我们发现 Google Web Fonts Helper 工具非常有用,可以帮助我们离线下载部分网页字体并在本地进行设置,因此请务必了解一下该工具。

无论您是将网页字体作为关键资源的一部分,还是恰好是 JavaScript,都请尽量帮助浏览器尽快提供关键资源。

实验性:优先级提示

今天,我们有一些特别的消息要与您分享。除了资源提示和预加载等功能外,我们还一直在开发一项全新的实验性浏览器功能,我们称之为“优先级提示”。

为初始可见内容设置优先级
图 20. 优先级提示

这是一项新功能,可让您向浏览器提示资源的重要性。它会公开一个新属性 - importance,其值为 low、high 或 auto。

这样,我们就可以传达降低不太重要的资源(例如非关键样式、图片或提取 API 调用)的优先级,以减少争用。我们还可以提高更重要内容(例如主打图片)的优先级。

就我们的 Oodle 应用而言,这实际上带来了一个可以优化的实际位置。

为初始可见内容设置优先级
图 21. 为初始可见内容设置优先级

在为图片添加延迟加载之前,浏览器会执行以下操作:我们有一个包含所有涂鸦的图片轮播,浏览器会在轮播开始时以高优先级获取所有图片。遗憾的是,轮播界面中间的图片对用户来说最重要。因此,我们所做的是,将这些背景图片的重要性设置为非常低,将前景图片的重要性设置为非常高,这在慢速 3G 网络上产生了 2 秒的影响,以及我们能够以多快的速度获取和渲染这些图片。 因此,用户体验非常积极。

我们希望在几周内将此功能引入 Canary,敬请期待。

制定网页字体加载策略

排版是优秀设计的基础,如果您使用的是网页字体,理想情况下您不希望阻止文本渲染,也绝对不希望显示不可见的文本。

现在,我们在 Lighthouse 中通过在加载网页字体期间避免显示不可见文本审核来突出显示此问题。

避免在加载 Web 字体时出现不可见文本
图 22. 避免在加载网页字体时出现不可见文本

如果您使用 font-face 块加载网页字体,则表示您允许浏览器决定在网页字体加载时间过长时该怎么做。某些浏览器会等待最多 3 秒钟,然后回退到系统字体,并在下载完成后最终将其替换为该字体。

我们正在努力避免这种不可见文本,因此在这种情况下,如果网页字体加载时间过长,我们就无法看到本周的经典涂鸦。幸好,借助名为 font-display 的新功能,您可以更好地控制此过程。

    @font-face {
      font-family: 'Montserrat';
      font-style: normal;
      font-display: swap;
      font-weight: 400;
      src: local('Montserrat Regular'), local('Montserrat-Regular'),
          /* Chrome 26+, Opera 23+, Firefox 39+ */
          url('montserrat-v12-latin-regular.woff2') format('woff2'),
            /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
          url('montserrat-v12-latin-regular.woff') format('woff');
    }

字体显示可帮助您根据交换所需的时间,决定 Web 字体的呈现或回退方式。

在本例中,我们使用的是 font-display: swap。Swap 会为字体系列提供 0 秒的阻塞期和无限长的交换期。这意味着,如果字体需要一段时间才能加载,浏览器会立即使用后备字体绘制文本。并在字体可用后进行替换。

就我们的应用而言,这种做法的好处在于,我们可以在很早的时候就显示一些有意义的文本,并在 Web 字体准备就绪后过渡到该字体。

字体显示结果
图 23. 字体显示结果

一般来说,如果您恰好在使用网页字体(就像大多数网站一样),请制定一个良好的网页字体加载策略。

您可以使用许多 Web 平台功能来优化字体加载体验,但也可以查看 Zach Leatherman 的 Web Font Recipes 代码库,因为它真的很棒。

减少会阻塞渲染的脚本

我们还可以将应用的其他部分提前到下载链的前端,以便更早地提供一些基本的用户体验。

在 Lighthouse 时间轴条带上,您可以看到,在所有资源加载的最初几秒内,用户实际上看不到任何内容。

“减少阻止渲染的样式表”优化建议
图 24. “减少阻止渲染的样式表”优化建议

下载和处理外部样式表会阻止渲染进程取得任何进展。

我们可以尝试通过提前提供一些样式来优化关键渲染路径。

如果我们提取负责此初始渲染的样式,并将其内嵌到 HTML 中,浏览器就能够立即渲染这些样式,而无需等待外部样式表到达。

在我们的案例中,我们使用了一个名为 Critical 的 NPM 模块,在构建步骤中将关键内容内嵌到 index.html 中。

虽然这个模块为我们完成了大部分繁重的工作,但要让它在不同的路由中顺利运行,还是有点棘手。

如果您不小心或网站结构非常复杂,那么如果您一开始没有规划应用 Shell 架构,则可能很难引入此类模式。

因此,尽早考虑性能问题至关重要。如果您在设计之初未考虑性能,那么在后续开发过程中很可能会遇到问题。

最终,我们的冒险得到了回报,我们成功实现了这一目标,应用开始更早地提供内容,从而显著缩短了首次有效渲染时间。

结果如何

我们对网站进行了大量性能优化。我们来看看结果。这是我们的应用在优化前后,在 3G 网络上通过中型移动设备加载的情况。

Lighthouse 性能得分从 23 分提高到 91 分。就速度而言,这是一个非常不错的进展。所有这些更改都是因为我们不断检查并遵循 Lighthouse 报告而做出的。如果您想了解我们如何在技术上实现所有改进,请随时查看我们的代码库,尤其是其中提交的 PR。

预测性性能 - 数据驱动的用户体验

我们相信,机器学习在许多领域都代表着令人兴奋的未来机遇。 我们希望未来能激发更多实验的一个想法是,真实数据可以真正指导我们打造的用户体验。

目前,我们对用户可能想要或需要的内容,以及值得预提取、预加载或预缓存的内容做出了许多武断的决定。如果我们猜对了,就能优先处理少量资源,但很难将这种做法推广到整个网站。

我们现在已经有数据可以更好地指导优化。 使用 Google Analytics Reporting API,我们可以查看网站上任何网址的下一个热门网页和退出百分比,从而得出应优先考虑哪些资源的结论。

如果我们将此功能与良好的概率模型相结合,就可以避免因过度预提取内容而浪费用户的数据。我们可以利用这些 Google Analytics 数据,并使用机器学习和马尔可夫链或神经网络等模型来实现这些模型。

Web 应用的数据驱动型打包
图 25. Web 应用的数据驱动型打包

为了促进这些实验,我们很高兴地宣布推出一项名为 Guess.js 的新计划。

Guess.js
图 26. Guess.js

Guess.js 是一个专注于为 Web 提供数据驱动型用户体验的项目。我们希望它能激发大家探索如何利用数据来提升网站性能,并在此基础上更进一步。所有这些都是开源的,现在就可以在 GitHub 上获取。该项目由 Minko Gechev、Gatsby 的 Kyle Matthews、Katie Hempenius 以及其他一些人与开源社区合作构建。

欢迎试用 Guess.js,并与我们分享您的想法。

摘要

分数和指标有助于提高网页速度,但它们只是手段,而不是目标本身。

我们都经历过在移动设备上网页加载缓慢的情况,但现在我们有机会为用户提供加载速度极快的更愉悦体验。

提升性能是一个过程。许多小改变可以带来大收益。通过使用合适的优化工具并关注 Lighthouse 报告,您可以为用户提供更优质、更具包容性的体验。

特别感谢:Ward Peeters、Minko Gechev、Kyle Mathews、Katie Hempenius、Dom Farolino、Yoav Weiss、Susie Lu、Yusuke Utsunomiya、Tom Ankers、Lighthouse 和 Google 涂鸦。