PubConsent CMP 如何通过一种让步策略(使用浏览器的 Scheduler API 来解决使用 Chrome 开发者工具发现的响应速度问题)将客户的 INP 最多降低了 64%。
意见征求管理平台 (CMP) 是一种工具,可帮助网站征求用户同意使用 Cookie 和跟踪技术,从而遵守隐私权法规。除了确保遵守法律法规这一主要目标之外,作为第三方脚本的 CMP 还必须确保将对效果和用户体验的影响降至最低。
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 产品中的一系列用户互动。
这种延迟会导致在执行任务期间,从视觉上看出面板处于锁定状态。由于它阻止了渲染更新很长一段时间,因此网页的 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);
});
};
PubTech 如何通过渲染布局优化进一步减少 TBT
应用收益策略后,CMP 的 INP 显著提高。事实上,在显著缩短事件处理脚本的处理时长后,我们发现了一次机会,可以针对关闭界面操作的下一次绘制进行进一步的渲染改进。此操作最初设计用于从 DOM 中移除元素。这带来了一些挑战,尤其是在 DOM 节点数量较多的网站上,导致渲染工作量意外增加。
为了解决从 DOM 中移除元素所需的渲染工作量增加的问题,我们引入了一种解决方案,该团队称为“延迟去渲染”。此方法会先在用户同意隐藏 CMP 意见征求对话框后,将 display: none
CSS 规则应用于该对话框。然后,使用 requestIdleCallback
将与 CMP 对话框关联的 DOM 节点的移除移至浏览器处于空闲状态的较晚时间点。事实证明,这种方法比在用户关闭意见征求对话框时移除 DOM 节点要快得多。
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 的客户很快就发现,我们的优化工作带来了积极的 INP 效果和业务指标结果。我们正在考虑利用客户提供的宝贵实时用户监控 (RUM) 数据,进一步提升 PubConsent CMP 的效果。这些数据会密切跟踪回归和进步情况,推动 PubTech 持续改进。
作为第三方,PubTech 还意识到,他们有机会大规模提升网站性能并提高响应速度,同时避免对业务 KPI 产生负面影响。开始实施这类改进永远不会为时已晚!
特别感谢 PubTech 首席技术官 Luca Coppola 为这项创新工作提供支持,以及 Google 的 Jeremy Wagner、Michal Mocny 和 Rick Viscomi。