将 TBT 降低 30 倍并迁移到 Next.js 帮助《经济时报》将 INP 降低了近四倍,从而使跳出率降低了 50%,页面浏览量提高了 43%。
下次绘制互动 (INP) 是一个评估网站对用户输入响应速度的指标。良好的响应速度意味着页面能够快速响应用户互动。页面 INP 值越低,其响应用户互动能力就越好。
模糊的开始
当 Google 最初引入 INP 作为一项实验性指标,并有可能发展成为 Core Web Vitals 指标之一时,《经济时报》团队接受了挑战,要在它成为核心指标之前解决这个问题,因为提供世界一流的用户体验对我们的核心业务价值观至关重要。
INP 是迄今为止最难解决的指标之一。起初,如何有效衡量 INP 并不明确。更困难的是缺乏社区支持,包括大多数真实用户监控 (RUM) 提供商尚未支持它。但是,我们有 Google RUM 工具,例如 Chrome 用户体验报告 (CrUX)、web-vitals
JavaScript 库以及其他支持它的工具,这让我们在评估前进方向时了解了自己的处境。当我们开始时,我们的 INP 在源站级别接近 1,000 毫秒。
在现场修复 INP 时出现的一个情况是,可以作为目标实验室指标之一是 Total Blocking Time (TBT)。TBT 已经有完善的文档记录并获得社区支持。尽管我们已经达到了 Core Web Vitals 的阈值,但我们在 TBT 方面做得不太好,因为当我们开始时它超过 3 秒。
什么是 TBT?我们采取了哪些步骤来改进它?
TBT 是一项实验室指标,用于衡量网页在页面加载期间对用户输入的响应速度。任何执行时间超过 50 毫秒的任务都被视为长任务,超过 50 毫秒阈值的时间称为阻塞时间。
TBT 的计算方法是将页面加载期间所有长任务的阻塞时间相加。例如,如果在加载期间有两个长任务,则阻塞时间的确定方式如下
- 任务 A 耗时 80 毫秒(比 50 毫秒多 30 毫秒)。
- 任务 B 耗时 100 毫秒(比 50 毫秒多 50 毫秒)。
页面的 TBT 将为:80 毫秒 (30 + 50)。TBT 值越低越好,并且 TBT 也与 INP 密切相关。
以下是我们在采取措施改进 TBT 前后进行的快速实验室比较


最大限度地减少主线程工作
浏览器的主线程处理所有事情,从解析 HTML、构建 DOM,到解析 CSS 和应用样式,以及评估和执行 JavaScript。主线程还处理用户互动,即点击、触摸和按键。如果主线程忙于执行其他工作,则可能无法有效地响应用户输入,并可能导致卡顿的用户体验。
这对我们来说是最困难的任务,因为我们有自己的算法来检测用户身份,以便根据订阅状态投放广告,以及用于 A/B 测试、分析等的第三方脚本。
我们首先采取了小步骤,例如降低不重要的业务资产的加载优先级。其次,我们对非关键工作使用了 requestIdleCallback
,这有助于减少 TBT。
if ('requestIdleCallback' in window) {
this.requestIdleCallbackId = requestIdleCallback(fetchMarketsData.bind(this), {timeout: 3000});
} else {
fetchMarketsData(); // Fallback in case requestIdleCallback is not supported
}
使用 requestIdleCallback
时,建议指定超时时间,因为它确保如果在给定时间已过且回调尚未被调用,它将在超时后立即执行回调。
最大限度地减少脚本评估时间
我们还使用 Loadable components 延迟加载了第三方库。我们还通过使用 Chrome DevTools 中的覆盖率工具分析页面,删除了未使用的 JavaScript 和 CSS。这帮助我们确定了在哪些区域需要 tree shaking 以在页面加载期间减少代码传输,从而减小应用程序的初始捆绑包大小。

减小 DOM 大小
根据 Lighthouse 的说法,大型 DOM 会增加内存使用量,导致更长的样式重新计算,并产生代价高昂的 布局重排。

我们通过两种方式减少了 DOM 节点数
- 首先,我们在用户请求时(点击时)渲染菜单项。这使 DOM 大小减少了约 1,200 个节点。
- 其次,我们延迟加载了不太重要的 Widget。
由于所有这些努力,我们显著降低了 TBT,并且我们的 INP 也相应地降低了近 50%。

在这一点上,我们几乎用尽了进一步降低 TBT(以及间接降低 INP)的简单方法,但我们知道我们还有很大的改进空间。这时我们决定将我们自定义构建的 UI 样板升级到最新版本的 React 以及 Next.js,以便更好地利用 Hook 来避免不必要的组件重新渲染。
由于与网站的其他部分相比,主题页面更新更频繁且流量相对较少,我们开始将我们的主题页面迁移到 Next.js。我们还使用了 PartyTown 将额外繁重的主线程工作卸载到 Web Worker,并使用了 requestIdleCallBack
等技术来延迟非关键任务。
改进 INP 对《经济时报》有何帮助?
源站上当前的 TBT 和 INP
在发布此文章时,我们源站的 TBT 为 120 毫秒,比我们开始优化工作时的 3,260 毫秒有所下降。同样,经过我们的优化工作,我们源站的 INP 为 257 毫秒,比之前的 1,000 多毫秒有所下降。

INP CrUX 趋势
主题页面收到的流量占总流量的比例要小得多。因此,它是进行实验的理想场所。CrUX 结果以及业务成果非常令人鼓舞,促使我们将我们的努力扩展到整个网站,以获得更多好处。

Akamai mPulse TBT 分析
我们使用 Akamai mPulse 作为我们的 RUM 解决方案,它用于衡量现场的 TBT。我们观察到 TBT 持续下降,这清楚地反映了我们为降低 INP 所做的努力的结果。如下面的屏幕截图所示,现场的 TBT 值最终从大约 5 秒降至约 200 毫秒。

业务成果
总的来说,我们将 TBT 降低 30 倍的努力,以及迁移到 Next.js,帮助我们将 INP 降低了近 4 倍,这最终导致主题页面的跳出率降低了 50%,页面浏览量提高了 43%。

结论
总而言之,INP 在很大程度上帮助确定了《经济时报》网站部分区域的运行时性能问题。它已被证明是积极影响业务成果的最有效指标之一。由于我们通过这项努力观察到了非常令人鼓舞的数字,我们有动力将我们的优化工作扩展到我们网站的其他区域,并获得更多好处。