PubConsent CMP 如何通过一种让步策略(使用浏览器的 Scheduler API 来解决使用 Chrome 开发者工具发现的响应能力问题)将客户的 INP 最多降低了 64%。
意见征求管理平台 (CMP) 是一种工具,可帮助网站征求用户同意使用 Cookie 和跟踪技术,从而遵守隐私权法规。除了确保合规性这一主要目标之外,作为第三方脚本,意见征求管理工具还必须确保对性能和用户体验的影响降到最低。
PubConsent CMP 是 PubTech 的最新产品。PubConsent CMP 在设计时以性能为主要目标,因此体积轻巧,可确保提供最佳用户体验,并尽可能减少对网站整体性能的影响。
引入 Interaction to Next Paint (INP) 指标后,PubTech 发现了 CMP 响应速度存在的问题。在本案例中,PubTech 展示了他们如何解决 PubConsent CMP 平台的响应速度问题,以及如何在 INP 于 2024 年 3 月成为 Core Web Vitals 指标之一之前改进 INP,从而展现他们对提供尽可能出色的 CMP 产品性能的坚定承诺。
为什么 PubTech 会关心效果?
与大多数 CMP 一样,PubConsent CMP 会将其意见征求管理功能作为第三方脚本在网站页面上实现。为了确保 CMP 集成成功,请务必减少 CMP 产品对性能(包括响应速度)的影响。
通过优先考虑性能并使 PubConsent CMP 脚本保持轻量级,网站所有者可以在纳入有价值的意见征求管理功能的同时,保持用户体验的质量,从而取得微妙的平衡。
鉴于 CMP 提供的功能的重要性及其对广告效果的影响,PubTech 设定了以下目标:
- 最大限度地减少 PubConsent CMP 产品对 INP 的影响。
- 减少归因于 CMP 产品的长任务。
- 缩短总屏蔽时间 (TBT),因为这可能会对网页的 INP 产生负面影响。
INP 的衡量方式
PubTech 使用 Chrome DevTools 进行了初步分析,并手动诊断了互动缓慢的问题。通过此工作流,PubTech 能够找出影响网页响应速度的具体问题。例如,在 CMP 产品中点击接受所有 Cookie 并关闭 Cookie 意见征求对话框的互动会导致一个耗时任务,从而延迟界面的呈现更新。如以下图片所示,在长时间任务完成之前,界面不会更新以显示对话框已关闭。
与接受所有 Cookie 的按钮一样,拒绝所有 Cookie 或自定义 Cookie 偏好的按钮在 PubConsent CMP 架构中也遵循相同的工作流。因此,本案例中详述的改进影响了 CMP 产品中的一系列用户互动。
![该流程展示了在用户点击 PubConsent CMP 中的“接受全部”按钮后,长任务如何阻止界面更新。一项长任务包含五个步骤,这会导致界面运行缓慢。](https://web.dev/static/case-studies/pubconsent-inp/image/fig-1.png?authuser=4&hl=zh-cn)
此延迟导致面板在执行任务期间呈现锁定状态。由于它明显阻止了渲染更新一段时间,因此网页的 INP 受到了负面影响。
PubTech 如何针对按钮和链接优化 INP
为了提高 INP,PubConsent CMP 采用了不同的收益策略。
让出高优先级任务
以下代码段中显示的 yieldToMainUiBlocking
方法旨在通过让出 scheduler.yield
(如果可用)来优化高优先级 JavaScript 任务,但如果 postTask
可用,则回退到优先级为 user-blocking
(高)的 postTask
,最后回退到无。
这里避免使用 setTimeout
,因为 yieldToMainUiBlocking
方法旨在处理内部 CMP 设置操作和应在让出时保留此类优先级的高优先级工作。这并不意味着只有实现了这些调度 API(在撰写本文时,这些 API 目前仅适用于基于 Chromium 的浏览器)的浏览器才能受益于本案例研究中详述的改进。即便如此,我们仍认为这种方法对于这些高优先级任务来说是可接受的渐进式增强。
function yieldToMainUiBlocking () {
return new Promise((resolve) => {
if ('scheduler' in window) {
if ('yield' in window.scheduler) {
return window.scheduler.yield().then(() => resolve(true));
}
if ('postTask' in window.scheduler) {
return window.scheduler.postTask(() => resolve(true), { priority: 'user-blocking' });
}
}
resolve(false);
});
};
中等任务和后台任务的让出
以下代码段中显示的 yieldToMainBackground
方法用于拆分优先级为 user-visible
(中)或 background
的长任务。如果 scheduler.yield()
可用,该逻辑会实现 scheduler.yield()
,但不同之处在于,它使用优先级为中等的 postTask
,并最终在非 Chromium 浏览器上回退到 setTimeout
。
function yieldToMainBackground () {
return new Promise((resolve) => {
if ('scheduler' in window) {
if ('yield' in window.scheduler) {
return window.scheduler.yield().then(() => resolve(true));
}
if ('postTask' in window.scheduler) {
return window.scheduler.postTask(() => resolve(true), { priority: 'user-visible' });
}
}
setTimeout(() => { resolve(true) }, 0);
});
};
![该流程展示了如何优化在用户点击 PubConsent CMP 中的“接受全部”按钮后阻止界面更新的长任务。现在,这五个步骤会尽可能让出,以便界面更快地更新其渲染。](https://web.dev/static/case-studies/pubconsent-inp/image/fig-2.png?authuser=4&hl=zh-cn)
yieldToMainBackground
让浏览器更快呈现下一次绘制(在本例中为关闭 CMP 界面)的过程。
PubTech 如何通过渲染布局优化进一步缩短了 TBT
应用收益策略后,CMP 的 INP 显著提高。事实上,在显著缩短事件处理脚本的处理时长后,我们发现了一次机会,可以针对关闭界面操作的下一次绘制进行进一步的渲染改进。此操作最初旨在从 DOM 中移除元素。这带来了一些挑战,尤其是在 DOM 节点数量较多的网站上,导致渲染工作量意外增加。
![Chrome DevTools 中“Performance”(性能)面板的屏幕截图,显示了轨迹的一部分,其中包含用于关闭 PubConsent CMP 中的界面对话框的 activity 调用堆栈。关闭界面对话框的任务本身会触发移除增加互动呈现延迟的 DOM 节点。](https://web.dev/static/case-studies/pubconsent-inp/image/fig-3.png?authuser=4&hl=zh-cn)
为了解决从 DOM 中移除元素所需的渲染工作量增加的问题,该团队引入了一种解决方案,称为“延迟取消渲染”。此方法会先在用户同意隐藏 CMP 意见征求对话框后,将 display: none
CSS 规则应用于该对话框。然后,使用 requestIdleCallback
将与 CMP 对话框关联的 DOM 节点的移除操作推迟到浏览器空闲的稍后时间。事实证明,这种方法比在用户关闭意见征求对话框时移除 DOM 节点要快得多。
![Chrome DevTools 中“Performance”(性能)面板的屏幕截图,显示与之前相同的轨迹,但经过优化。关闭 PubConsent CMP 的对话框后,初始操作是使用 CSS display: none 规则将其隐藏。然后,当浏览器稍后处于空闲状态时,系统会执行 DOM 节点移除操作。](https://web.dev/static/case-studies/pubconsent-inp/image/fig-4.png?authuser=4&hl=zh-cn)
PubTech 如何通过改进 IAB TCF 库进一步降低 INP
成功解决了 CMP 的大部分响应速度问题后,我们在其主要依赖项之一(IAB 透明度和用户意见征求框架 [TCF] 库)中发现了进一步改进的机会。
此库中计算开销最高的组件是“build strings”和“dispatch consent”。这些组件是 IAB TCF 库不可或缺的一部分。我们在专门针对 PubTech 需求的单独分支中对这些组件进行了以下优化:
- 重复使用解码流程的计算结果,该流程会针对需要读取用户意见的每个第三方回调执行。
- 避免了发布商限制编码流程中不必要的循环,并减少了此类循环。该流程会在用户同意后执行。
第一个优化缩短了 CMP 在挂钩到 IAB TCF 库的每个第三方回调上花费的时间。第二项优化缩短了“build strings”组件所需的处理时长。事实上,这项优化使每次用户表示同意时执行的循环次数最多减少了 60%。
结果
采用之前的效果出众的策略和新的呈现布局优化后,CMP 的 INP 最高提高了 65%。因此,PubConsent CMP 的响应速度和用户体验得到了极大提升。对于某些广告,通过优化广告请求时间,可见度甚至提高了 1.5%。
除了这些改进之外,我们还发现,在 IAB 的 TCF 库中,受影响的客户在移动设备上的 INP 最多提高了 77%,因为 TCF 导致的长任务最多减少了 85%。这有助于显著减少在网页的整个生命周期内执行的每个第三方回调的开销。
使用 PubConsent CMP 时,通过 INP 的来源数量提高了 400% 以上,在移动设备上从 13% 提高到了 55%。由于进行了 PubTech SDK 优化,部分客户的网页 INP 缩短了超过一半,从 470 毫秒缩短到了 230 毫秒。
![使用 PubTech CMP 的网站的来源 INP 通过率的屏幕截图。在桌面设备上,通过率从约 84% 提高到了 99.12%。在移动设备上,通过率从约 22% 提高到 55.46%。](https://web.dev/static/case-studies/pubconsent-inp/image/fig-5.png?authuser=4&hl=zh-cn)
![信息中心的屏幕截图,显示了第 75 个百分位的 RUM 数据中的 INP。从 2023 年 7 月/8 月开始,INP 略低于 500 毫秒,但到了 2024 年 2 月中旬,INP 略低于 200 毫秒,达到了“良好”阈值。](https://web.dev/static/case-studies/pubconsent-inp/image/fig-6.png?authuser=4&hl=zh-cn)
总结
PubTech 的客户很快就发现,我们的优化工作带来了积极的 INP 效果和业务指标结果。我们正在考虑利用客户提供的宝贵实时用户监控 (RUM) 数据,进一步提升 PubConsent CMP 的效果。这些数据会密切跟踪回归和进步情况,推动 PubTech 持续改进。
作为第三方,PubTech 还意识到,他们有机会大规模提升网站性能并提高响应速度,同时避免对业务 KPI 产生负面影响。开始实施这些改进永远不会为时已晚!
特别感谢 PubTech 首席技术官 Luca Coppola 为这项创新工作提供支持,以及 Google 的 Jeremy Wagner、Michal Mocny 和 Rick Viscomi。