時間のかかる広告介入への対応

デバイスのリソースを過度に消費する広告は、パフォーマンスの低下などの明らかな影響から、バッテリーの消耗や帯域幅の使用量の増加などの目立たない影響まで、ユーザー エクスペリエンスに悪影響を及ぼします。こうした広告は、暗号通貨マイニングなど、積極的に悪意のあるものから、意図しないバグやパフォーマンスの問題がある本物のコンテンツまで、多岐にわたります。

Chrome は、広告で使用できるリソースに制限を設け、制限を超えた場合、その広告をアンロードします。詳しくは、Chromium ブログのお知らせをご覧ください。広告のアンロードに使用されるメカニズムは、時間のかかった広告の問題を処理するです。

リソース消費の多い広告の条件

広告が重いと見なされるのは、ユーザーが広告を操作していない(タップやクリックなど)かつ、次のいずれかの条件を満たしている場合です。

  • メインスレッドを合計 60 秒以上使用している
  • 30 秒間のウィンドウで 15 秒以上メインスレッドを使用している
  • 4 メガバイトを超えるネットワーク帯域幅を使用している

広告フレームの子孫 iframe で使用されるすべてのリソースは、その広告で介入できる回数の上限にカウントされます。メインスレッドの時間制限は、広告の読み込みからの経過時間とは異なります。制限は、CPU が広告のコードを実行するのにかかる時間です。

介入のテスト

この介入は Chrome 85 でリリースされましたが、デフォルトでは、ユーザーのプライバシーを保護するためにしきい値にノイズと変動が追加されています。

chrome://flags/#heavy-ad-privacy-mitigations を [無効] に設定すると、これらの保護が削除されます。つまり、制限は純粋に上限に従って確定的に適用されます。これにより、デバッグとテストが容易になります。

介入がトリガーされると、容量の大きな広告の iframe に「広告が削除されました」というメッセージが表示されるようになります。記載されている [詳細] リンクをクリックすると、「この広告はデバイスで使用するリソースが多すぎるため、Chrome によって削除されました」というメッセージが表示されます。

サンプル コンテンツに適用された介入は、heavy-ads.glitch.me で確認できます。また、このテストサイトを使用して任意の URL を読み込み、独自のコンテンツを簡単にテストすることもできます。

テストする際は、介入が適用されない理由がいくつかあることに注意してください。

  • 同じページ内で同じ広告を再読み込みすると、その組み合わせは介入の対象外となります。閲覧履歴を消去し、新しいタグでページを開くと解決することがあります。
  • ページがフォーカスされたままであることを確認します。ページをバックグラウンドに移動(別のウィンドウに切り替える)と、ページのタスクキューが一時停止するため、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 は、介入時に指定されたコールバックをトリガーするために使用できる observe() メソッドを ReportingObserver に提供します。これは、デバッグを支援するためにレポートに追加情報を添付する場合に便利です。

// 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 のカスタム URL オプションを使うと、広告タグを設定した既製の iframe でこれをテストできます。Chrome DevTools を使用して、コンテンツが広告としてタグ付けされていることを検証できます。[レンダリング] パネル(その他アイコン メニュー > [その他のツール] > [レンダリング] からアクセス)で、[広告フレームをハイライト表示] を選択します。トップレベル ウィンドウや、広告としてタグ付けされていないその他のコンテキストでコンテンツをテストした場合、介入はトリガーされませんが、手動でしきい値に照らしてチェックできます。

フレームの広告ステータスは、[要素] ペインにも表示されます。ここでは、開始 <iframe> タグの後に ad アノテーションが追加されます。これは、[アプリケーション] パネルの [フレーム] セクションでも確認できます。広告タグが設定されたフレームには、[広告ステータス] 属性が含まれます。

ネットワーク使用量

Chrome DevTools の [Network] パネルを開いて、広告のネットワーク全体のアクティビティを確認します。繰り返し読み込みで整合性のある結果を得るには、[キャッシュを無効にする] オプションをオンにします。

DevTools のネットワーク パネル。
DevTools の [ネットワーク] パネル。

ページの下部にある転送額には、ページ全体で転送された金額が表示されます。上部の [フィルタ] 入力を使用して、広告に関連するリクエストのみに制限することをおすすめします。

たとえば、iframe のソースなど、広告の最初のリクエストが見つかった場合、リクエスト内の [イニシエータ] タブを使用して、トリガーされたすべてのリクエストを確認することもできます。

リクエストの [開始元] タブ。
リクエストのイニシエータ タブ。

リクエストの全体リストをサイズで並べ替えると、サイズが大きすぎるリソースを特定できます。一般的な原因としては、最適化されていない画像や動画などがあります。

リクエストをレスポンス サイズで並べ替える。
レスポンス サイズでリクエストを並べ替えます。

また、名前で並べ替えると、重複するリクエストを見つけやすくなります。介入のトリガーは、単一の大規模なリソースではなく、上限を超えるリクエストが繰り返し発生している可能性があります。

CPU 使用率

DevTools の [パフォーマンス] パネルは、CPU 使用率の問題の診断に役立ちます。まず、[キャプチャ設定] メニューを開きます。[CPU] プルダウンを使用して、CPU を可能な限り遅くします。CPU の介入は、ハイエンドの開発マシンよりも低電力のデバイスでトリガーされる可能性がはるかに高くなります。

[パフォーマンス] パネルでネットワークと CPU のスロットリングを有効にします。
[パフォーマンス] パネルでネットワークと CPU のスロットリングを有効にします。

次に、[記録] ボタンをクリックしてアクティビティの記録を開始します。長いトレースは読み込みにかなり時間がかかることがあるため、記録するタイミングと長さを試すことをおすすめします。録画が読み込まれたら、上部のタイムラインを使用して録画の一部を選択できます。スクリプト、レンダリング、ペイントを表す黄色、紫、緑の実線のグラフ領域に注目します。

[パフォーマンス] パネルのトレースの概要。
[パフォーマンス] パネルのトレースの概要

下部にある [ボトムアップ]、[呼び出しツリー]、[イベントログ] タブを確認します。これらの列を [Self Time] と [Total Time] で並べ替えると、コード内のボトルネックを特定できます。

[ボトムアップ] タブでセルフタイムで並べ替えます。
[ボトムアップ] タブで [セルフタイム] で並べ替えます。

関連するソースファイルもリンクされているため、[ソース] パネルに移動して各行の費用を確認できます。

[ソース] パネルに表示される実行時間。
[ソース] パネルに表示される実行時間。

一般的に、最適化が不十分なアニメーションが原因で、連続的なレイアウトやペイント オペレーションがトリガーされ、インクルードされているライブラリ内に隠れているコストのかかるオペレーションがトリガーされます。

誤った介入を報告する方法

Chrome は、リソース リクエストをフィルタリストと照合してコンテンツを広告としてタグ付けします。広告以外のコンテンツがタグ付けされている場合は、フィルタリング ルールに一致しないようにコードを変更することを検討してください。介入が誤って適用されたと思われる場合は、こちらのテンプレートを使用して問題を報告してください。介入レポートの例をキャプチャし、問題を再現するためのサンプル URL があることを確認してください。