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

如果广告在设备上消耗过多资源,就会对用户体验产生负面影响,从性能下降等明显影响到耗电或耗尽带宽配额等不太明显的影响。这些广告包括主动恶意广告(例如加密货币挖矿广告),也包括存在无意间 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 的 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',
    },
  },
];

诊断干预原因

广告内容只是 Web 内容,因此请使用 Lighthouse 等工具审核内容的整体效果。审核结果将提供关于改进的内嵌指导。您还可以参阅 web.dev/fast 集合。

您不妨在更隔离的环境中测试广告,这样做可能会有所帮助。您可以使用 https://heavy-ads.glitch.me 上的自定义网址选项,通过预先添加了广告代码的 iframe 进行测试。您可以使用 Chrome 开发者工具验证内容是否已标记为广告。在呈现面板(通过三点状图标 菜单依次选择更多工具 > 呈现)中,选择“突出显示广告框架”。如果在顶级窗口或未标记为广告的其他上下文中测试内容,系统不会触发干预,但您仍然可以手动检查是否达到阈值。

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

网络用量

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

DevTools 中的“Network”面板。
DevTools 中的“Network”面板。

页面底部的转移金额会显示针对整个页面转移的金额。不妨考虑使用顶部的过滤输入框,将请求限制为仅与广告相关的请求。

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

请求的“Initiator”(发起者)标签页。
请求的“发起者”标签页。

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

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

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

CPU 使用率

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

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

接下来,点击录制按钮开始录制活动。您可能需要尝试调整记录的时间和时长,因为较长的轨迹可能需要很长时间才能加载。录制内容加载完毕后,您可以使用顶部时间轴选择录制内容的一部分。重点关注图表中显示为黄色、紫色或绿色实线的区域,这些区域分别表示脚本、渲染和绘制。

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

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

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

关联的源文件也链接在此处,因此您可以通过该链接前往来源面板,查看每行代码的开销。

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

此处要注意的常见问题包括优化不佳的动画,这些动画会触发持续的布局和绘制,或者隐藏在包含的库中的高成本操作。

如何举报不当干预

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