应对过度消耗资源的广告的干预

如果广告消耗的设备资源过多,就会对用户体验产生负面影响,从明显的性能下降到不太明显的后果(例如耗尽电池电量或用完带宽配额)。这些广告的范围从主动恶意广告(例如加密货币挖矿程序)到包含意外 bug 或性能问题的正版内容广告。

Chrome 会限制广告可使用的资源,如果超出限制,则会卸载相应广告。如需了解详情,请参阅 Chromium 博客上的公告。用于卸载广告的机制是消耗过多资源的广告的干预措施

过度消耗资源的广告条件

如果广告未与用户互动(例如,用户未点按或点击广告),且符合以下任一条件,则该广告被视为“重型”广告:

  • 总共使用主线程超过 60 秒
  • 在任意 30 秒的时间窗口内,使用主线程的时间超过 15 秒
  • 使用超过 4 兆字节的网络带宽

广告框架的任何后代 iframe 使用的所有资源都计入干预相应广告的限制。请务必注意,主线程时间限制与自加载广告以来经过的时间并不相同。限制的是 CPU 执行广告代码所花费的时间。

测试干预

该干预措施已在 Chrome 85 中发布,但默认情况下,系统会向阈值添加一些噪声和可变性,以保护用户隐私。

chrome://flags/#heavy-ad-privacy-mitigations 设置为 Disabled 会移除这些保护措施,这意味着系统会根据限制确定性地应用限制。这应该会使调试和测试更加轻松。

当干预措施触发时,您应该会看到 iframe 中重型广告的内容被替换为“广告已移除”消息。如果您点击随附的详情链接,则会看到一条消息,其中说明:“对于您的设备来说,此广告使用的资源过多,因此 Chrome 已将其移除。

您可以在 heavy-ads.glitch.me 上查看应用于示例内容的干预措施。您还可以使用此测试网站加载任意网址,以便快速测试自己的内容。

请注意,在测试时,有多种原因可能会导致干预措施无法应用。

  • 在同一网页中重新加载同一广告将使该组合免于受到干预。清除浏览记录并在新标签页中打开相应网页有助于解决此问题。
  • 确保页面保持聚焦状态 - 将页面置于后台(切换到另一个窗口)会暂停该页面的任务队列,因此不会触发 CPU 干预。
  • 请确保在测试期间不要点按或点击广告内容,因为干预措施不会应用于收到任何用户互动的内容。

您需要做些什么?

您在自己的网站上展示第三方提供商的广告

无需采取任何行动,只需注意,用户在您的网站上可能会看到超出移除限制的广告。

您在自己的网站上展示第一方广告,或者您提供广告供第三方展示

请继续阅读,确保您通过 Reporting API 为重广告干预措施实现必要的监控。

您制作广告内容,或者您维护用于制作广告内容的工具

请继续阅读,确保您了解如何测试内容是否存在性能和资源使用问题。您还应参阅所选广告平台的指南,因为这些指南可能会提供额外的技术建议或限制,例如,请参阅 Google 的展示广告素材指南。 考虑直接在创作工具中设置可配置的阈值,以防止效果不佳的广告投放。

移除广告后会发生什么情况?

Chrome 中的干预措施通过名称恰当的 Reporting API 进行报告,报告类型为 intervention。您可以使用 Reporting API 通过以下方式接收有关干预的通知:向报告端点发送 POST 请求或在 JavaScript 中接收通知。

这些报告会在根广告标记 iframe 及其所有后代(即干预措施卸载的每个框架)上触发。这意味着,如果广告来自第三方来源(即跨网站 iframe),则由该第三方(例如广告提供商)负责处理举报。

如需为 HTTP 报告配置网页,响应应包含 Report-To 标头:

Report-To: { "url": "https://example.com/reports", "max_age": 86400 }

触发的 POST 请求将包含如下报告:

POST /reports HTTP/1.1
Host: example.com

Content-Type: application/report

[{
 "type": "intervention",
 "age": 60,
 "url": "https://example.com/url/of/ad.html",
 "body": {
   "sourceFile": null,
   "lineNumber": null,
   "columnNumber": null,
   "id": "HeavyAdIntervention",
   "message": "Ad was removed because its CPU usage exceeded the limit. See https://www.chromestatus.com/feature/4800491902992384"
 }
}]

JavaScript API 为 ReportingObserver 提供了一个 observe() 方法,该方法可用于在干预时触发提供的回调。如果您想向报告附加其他信息以帮助调试,此功能会非常有用。

// callback that will handle intervention reports
function sendReports(reports) {
  for (let report of reports) {
    // Log the `report` json via your own reporting process
    navigator.sendBeacon('https://report.example/your-endpoint', report);
  }
}

// create the observer with the callback
const observer = new ReportingObserver(
  (reports, observer) => {
    sendReports(reports);
  },
  { buffered: true }
);

// start watching for interventions
observer.observe();

不过,由于干预措施实际上会从 iframe 中移除网页,因此您应添加安全措施,以确保在网页完全消失之前捕获报告,例如 iframe 中的广告。为此,您可以将同一回调挂钩到 pagehide 事件。

window.addEventListener('pagehide', (event) => {
  // pull all pending reports from the queue
  let reports = observer.takeRecords();
  sendReports(reports);
});

请注意,为了保护用户体验,pagehide 事件会限制其中可执行的工作量。例如,尝试发送包含报告的 fetch() 请求会导致该请求被取消。您应使用 navigator.sendBeacon() 发送该报告,即使这样,浏览器也只是尽最大努力,无法保证。

JavaScript 生成的 JSON 类似于 POST 请求中发送的 JSON:

[
  {
    type: 'intervention',
    url: 'https://example.com/url/of/ad.html',
    body: {
      sourceFile: null,
      lineNumber: null,
      columnNumber: null,
      id: 'HeavyAdIntervention',
      message:
        'Ad was removed because its network usage exceeded the limit. See https://www.chromestatus.com/feature/4800491902992384',
    },
  },
];

诊断干预的原因

广告内容只是网络内容,因此请使用 Lighthouse 等工具来审核内容的整体效果。生成的审核结果会提供有关改进的内嵌指南。您还可以参阅 web.dev/fast 合集。

您可能会发现,在更隔离的环境中测试广告很有帮助。您可以使用 https://heavy-ads.glitch.me 上的自定义网址选项,通过预先制作的带有广告标记的 iframe 来测试此功能。您可以使用 Chrome 开发者工具验证内容是否已标记为广告。在渲染面板中(可通过三点状 菜单访问,然后依次选择更多工具 > 渲染),选择“突出显示广告框架”。如果在顶级窗口或其他未标记为广告的内容中测试内容,则不会触发干预,但您仍然可以手动检查是否超出阈值。

框架的广告状态也会显示在元素窗格中,其中在起始 <iframe> 标记后添加了 ad 注释。您还可以在“框架”部分下的“应用”面板中看到此信息,其中带有广告标记的框架将包含“广告状态”属性。

网络用量

在 Chrome 开发者工具中打开网络面板,查看广告的整体网络活动。您需要确保选中“停用缓存”选项,以便在重复加载时获得一致的结果。

开发者工具中的“网络”面板。
开发者工具中的“网络”面板。

页面底部的转移值将显示整个页面的转移量。不妨考虑使用顶部的过滤条件输入内容,将请求限制为仅与广告相关的请求。

如果您找到了广告的初始请求(例如 iframe 的来源),还可以使用请求中的 Initiator(发起者)标签页查看它触发的所有请求。

请求的发起方标签页。
请求的“发起者”标签页。

按大小对请求的总体列表进行排序,可以很好地发现过大的资源。常见原因包括未优化的图片和视频。

按响应大小对请求进行排序。
按响应大小对请求进行排序。

此外,按名称排序也是发现重复请求的好方法。触发干预的可能不是单个大型资源,而是大量重复请求,这些请求会逐渐超出限制。

CPU 使用率

开发者工具中的性能面板可帮助您诊断 CPU 使用率问题。第一步是打开拍摄设置菜单。 使用 CPU 下拉菜单尽可能减慢 CPU 速度。与高端开发机器相比,CPU 干预措施更可能在低功耗设备上触发。

在“性能”面板中启用网络和 CPU 节流。
在“性能”面板中启用网络和 CPU 节流。

接下来,点击记录按钮即可开始记录活动。您可能需要尝试不同的录制时间和时长,因为长时间的轨迹可能需要很长时间才能加载。加载录制内容后,您可以使用顶部的时间轴选择录制内容的某个部分。 重点关注图表中以纯黄色、紫色或绿色表示的脚本、渲染和绘制区域。

“性能”面板中跟踪记录的摘要。
“性能”面板中轨迹的摘要。

探索底部的自下而上调用树事件日志标签页。按自用时间总时间对这些列进行排序,有助于找出代码中的瓶颈。

在“自下而上”标签页中按“自用时间”排序。
在“自下而上”标签页中按“自用时间”排序。

相关联的源文件也会链接到此处,因此您可以点击该链接,在来源面板中查看每行的费用。

“来源”面板中显示的执行时间。
“来源”面板中显示的执行时间。

此处要查找的常见问题包括:触发持续布局和绘制的动画优化不佳,或包含的库中隐藏的代价高昂的操作。

如何报告不正确的干预措施

Chrome 会通过将资源请求与过滤条件列表进行匹配来将内容标记为广告。如果非广告内容已添加标记,请考虑更改该代码,以免与过滤规则匹配。如果您怀疑干预措施应用有误,可以通过此模板提出问题。请确保您已捕获干预报告的示例,并提供可重现问题的示例网址。