发布于 2026-01-05 3 阅读
0

诊断性能问题

诊断性能问题

我们已经讨论过性能工具网站关键指标。所以您知道如何衡量性能以及这些指标代表什么。现在到了最难的部分:如何改进它们?

Lighthouse 会在特定情况下提供一些提示,但网站越复杂,这些提示的作用就越小。完成基础优化之后,下一步该做什么?

计算器

首先需要了解的是,您的整体性能评分是基于三个核心 Web 指标(以及其他一些指标)的平衡计算得出的。在开发者工具中,Lighthouse 提供了一个计算器,您可以调整这些值并查看最终的整体评分。

要访问该计算器,请运行 Lighthouse 审核并滚动到“性能”部分。

屏幕截图显示了 Lighthouse 运行性能部分下方文本中的计算器链接。

它会打开计算器,这样你就可以开始调整指标,并了解需要平衡哪些因素才能提高绩效分数。

Lighthouse计算器页面截图。

你会注意到,在这个计算器中,有些指标的影响很小——例如速度指数。其他一些指标的优化空间也有限。但它是一个很好的起点,可以帮助你找到最大的性能瓶颈。

记录

接下来你需要做的就是记录性能数据。你可以在开发者工具中完成这项操作。

在开发者工具的性能选项卡中,注意录制按钮。

一些建议:

  • 使用隐身模式
  • 使用干净的 Chrome 配置文件
  • 使用 Chrome Canary 版本(这将在录制过程中显示核心网络指标)

按下录制键后,请务必刷新网站,以获取页面加载体验示例以及您正在寻找的指标。

表演标签页显示录像。

录制完成后,你就可以看到页面渲染在毫秒间的变化。你需要查找耗时较长的任务,或者触发页面重新加载的任务等等。

减轻

许多缓解方案都是开发人员长期以来关注的问题。这是因为,尽管核心指标是新的,但它们所突出和衡量的挑战却是相同的。

解决 FID(使用 TBT 估算)

首次输入延迟 (FID) 是网络性能的核心指标,但正如我们在上一篇文章中解释的那样,它通常使用总阻塞时间 (TBT) 来估算,有时也使用可交互时间 (TTI)。因此,这些缓解措施主要集中在改善 TBT 上。

长时间水合或渲染

致所有 React 用户!虚拟 DOM 是个很棒的工具,但当代码加载到浏览器时,需要一些额外的处理。渲染(或称水合)会阻塞主线程执行其他任务。而 TBT 正是用来估算并警告你这种情况的。

那么该如何解决这个问题呢?还有其他方法!

尽可能使用延迟加载。这些代码是否渲染在首屏下方?是否仅在表单提交时运行?是否仅在移动端导航栏打开时显示?尽可能将这些代码从主包中移除。如果您有兴趣了解如何入门,我写过一篇关于代码拆分的文章。

利用诸如 setTimeout 之类的函数。少做一些事情,让浏览器喘口气!浏览器很智能,如果你能错开它们需要处理的任务,它们就能顺利完成工作。

最后,请注意虚拟 DOM。复杂性确实很重要,因为更复杂的 DOM 树需要更长的加载时间。页面上每个元素都使用过多嵌套的提供程序和上下文是一种反模式。

重新计算

您是否注意到记录过程中出现了一系列变化,并且在开始阶段有一个非常短暂、一闪而过的重新计算块?这很重要,因为它会影响TBT,并且对CLS也有一定影响。

触发重新计算的因素之一是使用代码测量 DOM。更改样式或创建新元素都会影响性能。然而,即使是读取 DOM 也会产生影响,因为它会阻塞视口。

为了解决这个问题,请注意你修改样式的方式。如果你要更新 CSS,最好修改内联样式而不是样式块。这是因为调整内联样式只会改变单个元素,而修改样式块则会强制浏览器检查整个 DOM 树以查找潜在的更改。

CSS 动画的开销可能很大。理想情况下,你应该只在透明度或变换中使用动画。这些 CSS 属性不涉及布局更改,因此开销更小。此外,建议使用 ` transform3dtransform` 或` transform`willChange而不是`transform` 或 `transform`。最后,尽量避免在动画或事件中修改这些属性。如果你的 DOM 元素较小,这一点的影响就没那么大了。transformXtransformY

除了 CSS 之外,请避免使用这些 JavaScript 调用。如果必须使用,请在 `<script>` 标签内进行requestAnimationFrame。建议使用useLayoutEffect钩子来防止过度调用。始终遵循先读取后写入的原则。切勿在同一个请求中同时进行读取和写入操作,否则会重复计算两次。

requestIdleCallback最后,对于任何并非用户体验必需的内容,都应该使用 `<div>` 标签。如果可以等待,就应该等待。`<div>` 标签内的内容requestIdleCallback会在浏览器空闲时调用。它加载完毕后会隐藏,直到用户与之交互才会显示。这对于单页应用来说是一个绝佳的解决方案,尤其是在鼠标悬停于某个元素上时。阅读这篇文章了解更多信息。

漫长的绘画时间

TBT的另一个影响是渲染时间过长。这种情况主要发生在DOM庞大且复杂时。需要注意的是,这与大型虚拟DOM不同,尽管两者之间可能存在关联。

为了解决这个问题,请简化你的 HTML 结构。div“汤”式结构不好。另外,请注意,内联 SVG 可能会消耗大量资源!尤其是当 SVG 结构复杂时。如果你使用 SVG 来表示尺寸较小或固定大小的图像,那么将其转换为其他格式可能更有意义。

另一种提高此分数的方法是使用 CSS 属性content-visibility。但是,正如 Marcy Sutton在她的文章中指出的那样,应谨慎使用此属性。在地标上使用此属性会损害可访问性。

最后,尽量避免过度使用阴影效果或复杂的 CSS 滤镜。数量过多会消耗大量资源。

解决 CLS

接下来需要处理的核心网页优化是累积布局偏移 (CLS)。与 FID 不同,影响 CLS 的因素并不多。事实上,除了我们前面提到的重新计算之外,只有一个主要原因。

重新布局

当您的页面布局发生偏移时,CLS(页面布局稳定性)就会出现问题。这种情况只有在您多次重新布局页面时才会发生。许多页面都会出现这种情况,但您可以限制布局次数,并确保它不会导致明显的视觉偏移。

更改样式或插入元素会导致重新布局。如果还有其他方法可以实现您想要的功能,请务必尝试!

占位符是你的好帮手。如果你要加载一些需要时间渲染的内容,比如图片,在 DOM 中放置一个尺寸匹配的元素可以防止页面在渲染时发生较大的布局偏移。

如果采用延迟加载字体的方式,尽量选择与系统字体风格相近的字体。字体差异可能会导致明显的视觉效果偏差。此外,使用字体切换功能也是个不错的选择。

解决 LCP

最后一个核心网页要素是最大内容绘制(LCP)。是时候谈谈资源优化了!

图片或字体加载完毕

确保图片和字体加载速度快是提高 LCP 的主要方法,因为这些资源通常是网站上最大的资源。

主图最好从您自己的域名加载。从第三方来源加载通常会比较慢。

对于字体,请添加预加载标签。这样浏览器就可以为您优化字体下载。

阻止渲染的下载

还有许多因素会阻碍这些大型资源的渲染。主要包括阻塞脚本、加载样式表以及非异步脚本标签。

如果您要内联脚本,请确保它们位于文件末尾。浏览器解析 DOM 时,每次遇到脚本都必须暂停并等待其执行完毕。将脚本放在文件末尾可以确保 DOM 解析不会被阻塞。

给脚本添加类型module标记还可以防止它们阻塞渲染。

最后,请确保样式表位于所有脚本标签之前。浏览器解析完 DOM 后,需要访问 CSSDOM 来创建渲染树。如果样式表访问受阻,浏览器就无法创建渲染树,从而进一步延迟页面渲染。

就这样!

你可能在想,“这就完了”是什么意思?!这内容也太多了吧!你说得完全正确。

值得注意的是,这些优化措施中有很多并不适用于您的页面。但对于那些适用的优化措施,您并非要完全消除每次重新计算或避免下载大型资源。这些操作对于构建一个出色且动态的网站至关重要。我们的目标是尽可能减少它们对用户体验的影响,并以最佳性能的方式处理它们。

文章来源:https://dev.to/laurieontech/diagnosing-performance-issues-3k5j