Trendyol 如何将 INP 降低 50%,使点击率提高 1%

本案例研究介绍了调试和改进 INP 的分步工作流程 Trendyol 通过利用 Google 工具(例如 PageSpeed)在 React 中使用的 Insights (PSI)Chrome 开发者工具scheduler.yield API

Gilberto Cocchi
Gilberto Cocchi

商品详情页是所有电子商务网站的两个关键组成部分 (PLP) 和商品详情页面 (PDP)。电子商务流量通常来自 比如电子邮件广告系列、社交媒体 广告。因此,确保 PLP 体验达到 经过精心设计,缩短用户完成购买所需的时间。确定优先次序 用户体验质量是取得成功的关键所在。研究出版物 “Milliseconds Make Millions”等数据显示, 网络性能对花钱和互动的意愿 与在线品牌合作。

Trendyol 是一个电子商务平台,拥有大约 3,000 万客户, 24 万卖家,这促使我们成为土耳其第一家企业 的估值超过 100 亿美元,是全球领先的电子商务平台之一, 整个世界。

为了实现尽可能大规模提供最佳用户体验的目标 同时保持内容的灵活性,并使用旧版本的 React 的 Trendyol 将 Interaction to Next Paint (INP) 作为关键指标 改进。此案例研究介绍了 Trendyol 在 Google Cloud 上改进 INP 的过程 PLP,INP 降低了 50%,搜索次数提升了 1% 结果业务指标

Trendyol 的 INP 调查流程

INP 用于衡量网站对用户输入的响应情况。良好的 INP 表示 确保浏览器能够快速可靠地响应所有用户输入, 重新绘制页面,这是良好用户体验的关键组成部分。

Trendyol 为了改进 PLP 中的 INP,首先对 在做出任何改进之前改善用户体验根据 PSI 报告 PLP 真实用户体验的 INP 为 963 毫秒, mobile所示,如下图所示。

<ph type="x-smartling-placeholder">
</ph> Trendyol 的 INP(根据 PageSpeed Insights 中的 CrUX 读数得出)。截至 2023 年 9 月 5 日,Trendyol 的 INP 为 963 毫秒,处于“较差”范围。 <ph type="x-smartling-placeholder">
</ph> PSI 截至 2023 年 9 月 5 日发布的 Trendyol 的 INP。

为确保良好的响应速度,网站所有者应力争达到低于或 200 毫秒,则表示当时 Trendyol 的 INP 处于 “很差”范围。

幸运的是,PSI 为 Chrome 用户 体验报告 (CrUX) 和详细的实验室诊断数据。查看实验 Lighthouse 的 JavaScript 执行时间审核建议, search-result-v2 脚本占用主线程的时间比其他脚本长 脚本。

<ph type="x-smartling-placeholder">
</ph> Trendyol 网站为 Lighthouse 读出长任务的来源。长任务的一个主要来源是处理 Trendyol PLP 上执行搜索结果的脚本。 <ph type="x-smartling-placeholder">
</ph> Lighthouse 自 9 月起评估 Trendyol 的 JavaScript 执行时间 2023 年 5 月 5 日。

为了确定实际的瓶颈,我们使用了 Chrome 中的性能面板 开发者工具对 PLP 体验进行问题排查并确定 问题。在 Chrome 开发者工具中模拟 CPU 速度降低 4 倍的情形 在主线程上发现了一项耗时 700-900 毫秒的任务。如果主要 线程被其他任务占用的时间超过 50 毫秒, 无法及时响应用户的输入内容, 用户体验。

<ph type="x-smartling-placeholder">
</ph> Chrome 开发者工具中针对 Trendyol 的 PLP 进行性能分析会话的屏幕截图。描述的长任务运行 737.6 毫秒,是 Intersection Observer 回调的一部分。 <ph type="x-smartling-placeholder">
</ph> Trendyol PLP 上的长任务性能分析器 面板。

运行时间最长的任务是由对 React 组件中的搜索结果脚本。此时,我们开始 将冗长的任务分解成若干小段,为浏览器提供更多 响应优先级更高的工作(包括用户互动)的机会。

事实证明,使用触发 React 的 setState 操作 在 Intersection Observer 回调内进行重新渲染的成本很高, 这可能会在低端设备上 太长。

开发者过去采用的将任务拆分为较小任务的一种方法 涉及setTimeout。我们利用这项技术推迟了 setState 调用。虽然 setTimeout 允许延迟 JavaScript 执行时,它不会提供对优先级的任何控制。这导致 我们加入 scheduler.yield 源试用,以确保 在让出主线程后继续脚本执行:

/*
* Yielding method using scheduler.yield, falling back to setTimeout:
*/
async function yieldToMain() {
  if('scheduler' in window && 'yield' in scheduler) {
    return await scheduler.yield();
  }

  return new Promise(resolve => {
    setTimeout(resolve, 0);
  });
}

/*
* Yielding to the main thread before changing the state of the component:
*/
const observer = new IntersectionObserver((entries) => {
  entries.forEach(handleIntersection);
  const maxNumberOfEntries = Math.max(...this.intersectingEntries);

  if (Number.isFinite(maxNumberOfEntries)) {
    await this.yieldToMain();

    this.setState({ count: maxNumberOfEntries });
  }
}, { threshold: 0.5 });

将此生成方法添加到 PLP 代码中后,INP 得到了改进,因为 主要的长任务被拆分成了一系列较小的任务 例如用户互动和后续呈现工作, 比其他情况早一些。

<ph type="x-smartling-placeholder">
</ph> Chrome 开发者工具中针对 Trendyol 的 PLP 进行性能分析会话的屏幕截图。之前运行 737.6 毫秒的长任务现在被拆分成了几个小任务。 <ph type="x-smartling-placeholder">
</ph> 将任务拆分为多个较小的任务。

请注意,Trendyol 使用 PuzzleJs 框架来实现微前端 使用 React v16.9.0 构建架构。在 React 18 中, ,但出于多种原因,Trendyol 无法以这种方式升级。 。

业务成效

为了衡量实施的 INP 改进措施的影响,我们进行了 A/B 测试, 了解业务指标受到了怎样的影响。总体而言,我们对 PLP 的更改 大幅提升,包括 INP 降低 50% 和 1% 从商品详情页面跳转到商品详情页面的点击率提升幅度 。在下图中,您可以看到 INP 在 PLP 随时间的变化:

<ph type="x-smartling-placeholder">
</ph> Trendyol 第 75 个百分位 INP 在过去 6 个月内的屏幕截图。到六个月结束时,Trendyol 的 INP 从近 1,400 毫秒降至将近 650 毫秒。 <ph type="x-smartling-placeholder">
</ph> 第 75 个百分位的 INP 随着时间推移而提高。

总结

优化 INP 是一个复杂的迭代过程,但可以简化流程 以及清晰的工作流程一种用于调试和改进您的 网站的 INP 取决于您是否收集自己的现场数据。如果您 PSI 和 Lighthouse 是一个很好的起点。确定 则您可以使用开发者工具进行更深入的挖掘,以尝试重现 问题。

不时让给主线程,以便为浏览器提供更多 提供紧急工作机会将使您的网站响应更快, 客户能够获得更好的体验新版日程安排 API 让此任务变得更轻松。scheduler.yield()

特别感谢来自 Google 技术团队的 Jeremy Wagner、Barry Pollard 和 Houssein Djirdeh Google 和 Trendyol 工程团队,感谢他们对这项工作所做的贡献。