Lighthouse 是用于测试网页性能工具最有用的技术之一。它具备了自动化,并可以测量网站的可访问性和 SEO。更重要的是,它目前是开源的并且可以免费使用。同时,它可以用来测试渐进式 Web 应用程序。
Web 应用程序的 SEO 性能成为过去几年最热门的话题之一。
今天,性能不仅仅是渲染应用程序所需的时间。一些不良的体验带来的多米诺骨牌效应更会损害你的应用程序。
你是否知道自 2010 年以来 Google 一直在关注网站的访问网络速度排名吗?
同时,你是否知道应用程序的性能对用户体验,甚至收入的巨大影响吗?以下是谷歌给出的一些证据:
但别担心,我准备了一份清单,可以帮助你提高应用程序的整体速度,同时改善用户体验和搜索引擎优化。我根据 Lighthouse 是提供的性能指标,列出了这份清单,希望能帮助你以清晰直观的方式改进你的应用程序。
让我们首先了解 Lighthouse 是如何理解和计算性能分数的。
Lighthouse 是用于提高网页质量的开源自动化工具。你可以针对任何网页或需要身份验证的网页运行它。它会对性能、可访问性、渐进式 Web 应用程序、SEO 等进行计算,最终得出各方面的评价分数。
Lighthouse 的性能检测是基于 Web Vitals 指标来测量页面的性能。
Web Vitals
,即 Google 给的定义是一个良好网站的基本指标(Essential metrics for a healthy site)。在过去要去衡量一个高质量网站,需要的指标太多,且有些指标计算很复杂,所以,Google 推出 Web Vitals 就是为了简化这个过程,用户仅仅需要关注 Web Vitals 即可。
下图中,我总结了一下 Web Vitals 给出的指标:
其中:
PerformanceObserver
观察类型为 longtask
的条目,然后可以根据耗时较长的条目的 startTime
和duration
,来大致确认页面处于 idle
的时间,从而确定 TTI 指标。假设我们的应用程序包含 20 个任务:
TBT 只关心 60 毫秒的任务(更准确地说,是 50 毫秒阈值与值本身之间的差异),所以我们的最终结果将是:
AMOUNT x (VALUE – THRESHOLD) = RESULT
10 x (60ms – 50ms) = 100ms
接下来,我们根据上面提到的指标,试着提升应用程序的 Lighthouse 分数。
为什么字体会影响你的灯塔分数?这是因为它们的使用方式不仅会影响页面速度(不同的字体有不同的大小),而且会对查看者在不查看页面时的查看方式产生深远影响。以下是一些需要注意的事项:
字体子集:一些字体有更小的变体,称为“子集”。 它们包含更少的字形,这进一步减小了文件的大小。例如,某些字体具有仅包含拉丁字母和字符的“拉丁”子集。
假设我们想使用字体的所有变体(在这个例子中是 9 个文件)。我们将之前的结果乘以 9,并将其大小与单个可变字体文件进行比较。
脚本也会影响应用的性能——尤其是当它们在不需要的地方出现瓶颈或占用宝贵的加载时间时。处理这方面的方法:
async
或 defer
延迟加载第三方脚本,以防止阻塞应用程序的主线程。你还可以使用 next/script
来设置脚本的优先级。CSS over CSS-in-JS
解决方案。在样式方面,您可能需要考虑一种更“老式”的方式。因为在 SSR 应用程序中,我们不想用更多的 JavaScript 占用主线程。这就是为什么 CSS-in-JS
解决方案不是最适合 Next.js 应用程序的原因。此外,Next.js
已经内置了很多 CSS 优化方案,比如类名和样式缩小、sass 支持、配置 postcss。
FOUT
(无样式文本的闪烁)或看到空白屏幕,应该始终通过使用字体上的 font-display
属性来控制字体的加载。分析 Bundles
包可以很好地发现应用的 Chunk
的数量和大小。
Bundle-wizard
。它是 @next/bundle-analyzer
的一个很不错的替代品,它允许我们检查我们的应用程序包。在我看来,它比其他工具有 3 大优势:chunk
的覆盖范围chunk
拆分。减少 bundles
包大小的一个好方法是将它们分成更小的部分。我们的应用程序更容易加载多个较小的块而不是几个大块。幸运的是,webpack 确实允许我们拆分合并的块。此外,我们可以控制模块的优先级。monorepo
架构中工作时,我们可能会得到多次捆绑的包。同样,webpack config
带有一个可以合并我们重复的块的属性。每当可见元素将其位置从一个渲染帧更改为下一帧时,就会发生布局转换。
最常见的影响CLS的分数的有:
因此,需要为动态内容保留空间。为了防止任何意外的布局变化,我们应该始终为尚未渲染的内容保留空间。
有很多很棒的方法,比如骨架加载,它模仿给定组件的一般外观,包括它的宽度和高度。这样,我们将保留确切的空间,从而消除 CLS。
但有时,我们不必使用任何花哨的东西。我们可以只插入一个空的占位符框,这将确保用户没有不愉快的体验。
图像可能是最臭名昭著的页面速度的恶棍。我们有更多的技巧可以让这个问题成为不是问题:
webp
或 jpeg2000
文件扩展名提供图像。它比传统的 jpeg 或 png 轻得多,而且没有明显的质量损失。 有许多库可以在上传过程中将图像转换为 webp,因此请随意使用它们。但请始终记住,某些较旧的浏览器可能不支持该扩展,因此请准备适用格式的后备版本。Sharp
这样的库允许我们生成同一张图像的多种尺寸。要显示它们,我们可以使用 <picture>
标签或 img srcSet
属性。loading=”lazy”
属性。LCP
元素。预加载“告诉”浏览器需要比正常情况更早地获取内容。Next/image
组件。Next/Image
组件,它将通过转换为 webp、调整大小、延迟加载和预加载 API 为我们优化图像。有时,在 SEO 性能方面,JavaScript 可能会成为反派。为了提高应用程序的分数,我们可以避免一些常见错误:
Next/dynamic
是一个很好的代码拆分工具。使用简单的 API,我们可以将组件拆分为单独的块,这些块将按需加载。我们还可以控制组件是否应该在服务器端呈现。export default
导出文件, 而是导出需要用到的模块。例如:export const function test() {}
如果我们已经达到了让我们满意的性能水平,那么随着时间的推移将其保持在同一水平会很好。有一些工具可以帮助我们做到这一点:
Bundle-wizard
。在我们的应用程序增长时不时运行此工具是一个很好的做法,以确保包大小保持较小,并且我们不会遇到任何意外的块问题。PageSpeed Insights / Lighthouse
。当然,我们衡量应用程序性能的主要工具是 Lighthouse。我们可以通过 Chrome 浏览器中的开发工具运行它,也可以通过 PSI 网站运行它。像 Lighthouse 或 WebPageTest 这样的工具有时会产生误导,因为它们总是在稳定的互联网连接、最新版本的 Chrome 等环境下工作……而对于我们的最终用户而言,情况并非总是如此。通常,用户在给定页面上的表现可能比 Lighthouse 建议的要差得多。
Web App 的性能不是修复一次就可以完成的。 它更像是一个随着应用程序的增长而不断检查、分析和改进应用程序的过程。幸运的是,我们可以而且应该尽可能地自动化这个过程。
因此,设置正确的工作流程可以防止我们推送会破坏我们的应用程序性能的代码,在实施过程中发现错误,甚至指出我们应该关注的痛点。