《经济时报》挑战 INP 问题

将 TBT 减少 30 倍并迁移到 Next.js 后,The Ecomonic Times 将 INP 减少了近 4 倍,从而使跳出率降低了 50%,网页浏览量提高了 43%。

Daya Ram Yadav
Daya Ram Yadav
Saurabh Rajpal
Saurabh Rajpal

Interaction to Next Paint (INP) 是一个指标,用于评估网站对用户输入的响应能力。良好的响应速度意味着网页可以快速响应用户互动。网页的 INP 越低,就越能响应用户互动。

良好的 INP 值为 200 毫秒或更短,不良值不超过 500 毫秒,两者之间的任何值都需要改进。

模糊的开始

当 Google 最初将 INP 作为一项有可能发展成为 Core Web Vitals 指标的实验性指标时,经济时报团队便迎接挑战,在努力将其转化为一个指标之前加以解决,因为提供世界一流的用户体验对于我们的核心业务价值至关重要。

INP 一直是迄今为止最难解决的指标之一。最初,并不清楚如何有效衡量 INP。更困难的是缺乏社区支持,包括大多数实时用户监控 (RUM) 提供商目前还不支持社区支持。不过,我们有 Chrome 用户体验报告 (CrUX)web-vitals JavaScript 库等 Google RUM 工具以及其他支持此类工具的工具,这让我们可以了解自己在评估未来路线时所处的位置。开始时,我们的 INP 在原始级别接近 1,000 毫秒。

在解决实际应用中的 INP 问题时,我们发现其中一项实验指标可能是“Total Blocking Time (TBT)”。TBT 已有社区文档记录并得到社区支持。尽管核心网页指标已经达到阈值,但是我们在 TBT 方面表现不佳,因为开始时只有 3 秒以上的时间。

什么是 TBT?我们采取了哪些措施来对其进行改进?

TBT 是一项实验室指标,用于衡量网页在网页加载期间对用户输入的响应速度。执行任何耗时超过 50 毫秒的任务都会被视为耗时较长的任务,达到 50 毫秒阈值之后的时间称为阻塞时间。

TBT 的计算方法是将网页加载期间所有长时间运行的任务的阻塞时间总和。例如,如果在加载期间有两个长时间运行的任务,则阻塞时间按如下方式确定:

  • 任务 A 用时 80 毫秒(比 50 毫秒多 30 毫秒)。
  • 任务 B 用时 100 毫秒(比 50 毫秒多 50 毫秒)。

网页的 TBT 将为:80 毫秒 (30 + 50)。TBT 越低越好,TBT 也与 INP 的关系很好

以下是在采取措施改进 TBT 前后的简要实验对比结果:

Chrome 开发者工具的性能面板中的启动期间长时间任务的合成图片,以及页面指标报告。主线程在网页加载期间被阻塞 3,260 毫秒。
启动期间的主线程,优化 TBT 之前。TBT 为 3260 毫秒。
Chrome 开发者工具的性能面板中的启动期间长时间任务的合成图片,以及页面指标报告。主线程在网页加载期间处于阻塞状态 120 毫秒。
优化 TBT 后启动期间的主线程。TBT 为 120 毫秒。

最大限度地减少主线程工作

浏览器的主线程会处理所有工作,包括解析 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 组件延迟加载第三方库。此外,我们还使用 Chrome 开发者工具中的覆盖率工具分析网页,从而移除未使用的 JavaScript 和 CSS。它帮助我们确定了需要进行摇树优化的区域,以便在网页加载期间减少所植入的代码,从而缩减应用的初始软件包大小。

Chrome 开发者工具中的覆盖率工具的屏幕截图。在这里,该工具会显示网页加载期间未使用的 JavaScript 和 CSS 文件部分。

缩减 DOM 大小

根据 Lighthouse 报告,大型 DOM 会增加内存使用量、导致样式重新计算时间延长,并产生代价高昂的布局自动重排

Lighthouse 中 DOM 大小审核的屏幕截图。报告的 DOM 元素数为 2,706 个元素。

我们通过以下两种方式减少了 DOM 节点的数量:

  • 首先,我们应用户请求(点击时)呈现菜单项。它将 DOM 大小缩减了约 1200 个节点。
  • 其次,我们延迟加载不太重要的 widget。

经过所有这些努力,我们显著降低了 TBT,同时 INP 也减少了近 50%:

CrUX 中 INP 审核的屏幕截图。该网页的 INP 为 539 毫秒,超出了“欠佳”阈值。

到目前为止,为了进一步减少 TBT(和 INP),我们几乎已经没有成功的胜利,但我们知道还有很大的改进空间。这时,我们决定将自定义的界面样板与 Next.js 一起升级到最新版 React,以便更好地利用钩子,避免不必要的组件重新渲染。

由于与网站的其他部分相比,更新更频繁,流量相对较少,我们开始将主题页面迁移到 Next.js。我们还使用 PartyTown 将额外的繁重主线程工作分流给 Web 工作器,以及使用 requestIdleCallBack 等技术来推迟非关键任务。

改进 INP 对《经济时报》有何帮助?

原点的当前待定和 INP

截至发布这篇博文时,源的 TBT 为 120 毫秒,而原来我们开始优化时的 3,260 毫秒。同样,我们初始的 INP 完成优化后用时 257 毫秒,从 1,000 多毫秒减少到 1,000 毫秒。

CrUX 中 INP 审核的屏幕截图。该网页的 INP 为 257 毫秒,处于“需要改进”阈值范围内。

INP CrUX 趋势

主题网页上获得的流量在总流量中所占的比例要低得多。因此,这里非常适合进行实验。CrUX 取得的成效和业务成果非常喜人,促使我们在整个网站上扩大工作,以获得进一步收益。

CrUX 中直观呈现的 INP 分布情况屏幕截图,从 2022 年 7 月开始,到 2022 年 10 月结束。“欠佳”和“需要改进”阈值范围内的值有所下降,而“良好”阈值范围内的值有所提高。

Akamai mPulse TBT 分析

我们使用 Akamai mPulse 作为 RUM 解决方案,该解决方案可以衡量现场的 TBT。我们观察到,TBT 持续下降,这清楚地反映了我们为减少 INP 而付出的努力所取得的成果。如以下屏幕截图所示,该字段中的 TBT 值最终从大约 5 秒下降到大约 200 毫秒。

Akamai mPulse 中图表的屏幕截图,显示了在大约一个月内,TBT 呈下降趋势。

业务成效

总的来说,通过将 TBT 减少 30 倍,再加上迁移到 Next.js,我们得以将 INP 减少近 4 倍,最终使主题页面的跳出率降低了 50%,网页浏览量提高了 43%

Google Analytics(分析)比较网页浏览量与跳出率的屏幕截图。由于对《经济时报》网站中的 INP 进行了优化,其跳出率降低了 50%,网页浏览量增加了 43%。

总结

总而言之,INP 广泛帮助确定了《经济时报》网站部分部分的运行时性能问题。事实证明,它是对业务成果产生积极影响的最有效指标之一。通过这一举措取得非常喜人的数据,我们迫不及待地想要将优化工作扩展到网站的其他领域,收获更多收益。