実装に関する一般的な誤りの回避

GPT の実装時によく見られるミスを以下に示します。このような実装は、現在のバージョンの GPT で適切に機能するように見えますが、今後も引き続き利用できるという保証はありません。極端な場合は、このような実装によって予期しない方法で広告配信が中断されることがあります。 サポートされていない実装と見なされます。

各シナリオでは、示された問題を解決するための推奨アプローチを示します。

このリストは、発生する可能性のある問題をすべて網羅しているわけではありませんが、対処する必要がある問題の種類を特定するためのガイドとして役立ちます。

実装方法によっては、そうした変更が必要なサイトをすべて確認する必要があるかもしれません。

よくある誤り

シナリオ 1: GPT JavaScript ライブラリの非公式なコピーを使用する

ユースケースの概要 gpt.js、pubads_impl.js、または独自のサーバーから読み込むライブラリをホストする、または非公式のソースからそれらのファイルを読み込む。
エラーのあるコード スニペットの例
// Incorrect: Accessing these files from an unofficial source
<script async src="https://www.example.com/tag/js/gpt.js"></script>
おすすめのエラーの修正方法
// Correct: Access these files from a Google domain
<script async src="https://securepubads.g.doubleclick.net/tag/js/gpt.js"></script>
// Also correct, if using Limited Ads
<script async src="https://pagead2.googlesyndication.com/tag/js/gpt.js"></script>

シナリオ 2: gpt.js スクリプトタグ リスナーを利用する

ユースケースの概要 API の一部は pubads_impl.js ファイルで提供されているため、JavaScript ファイル gpt.js の読み込み時に GPT API を呼び出せる状態になっていると仮定します。スクリプトタグにアタッチされたイベント リスナー内からなんらかの方法で(フレームワークを含む)API に依存することは誤りです。
エラーのあるコード スニペットの例
var tag = document.createElement('script');
tag.type = 'text/javascript';
tag.src = (useSSL ? 'https:' : 'http:') +
        ‘//www.googletagservices.com/tag/js/gpt.js';
// Incorrect: Attaching a callback to the script’s onload event.
tag.onload = callback;
var node = document.getElementsByTagName('script')[0];
node.parentNode.insertBefore(tag, node);
おすすめのエラーの修正方法
// Make sure that googletag.cmd exists.
window.googletag = window.googletag || {};
googletag.cmd = googletag.cmd || [];
// Correct: Queueing the callback on the command queue.
googletag.cmd.push(callback);
修正の説明 / 説明 googletag.cmd は、GPT の準備ができたらすぐに実行されるコマンドのリストを保持します。これは、GPT が読み込まれたときにコールバックが実行されるようにする適切な方法です。

シナリオ 3: googletag オブジェクトを確認して、GPT の準備ができているかどうかを確認する

ユースケースの概要 JavaScript ファイル gpt.js の読み込み時または googletag オブジェクトの定義時に GPT API の準備が整っていない可能性があるため、オブジェクトで GPT API が使用可能かどうかを確認するのは適切ではありません。
エラーのあるコード スニペットの例
// Incorrect: Relying on the presence of the googletag object
// as a check for the GPT API.
if (typeof googletag != 'undefined') {
 functionProcessingGPT();
}
おすすめのエラーの修正方法
// Correct: Relying on googletag.apiReady as a check for the GPT API.
if (window.googletag && googletag.apiReady) {
 functionProcessingGPT();
}
修正の説明 / 説明 API 呼び出しの準備ができるとすぐに、GPT はブール値フラグ googletag.apiReady に入力されます。これにより、信頼性の高いアサーションができるようになります。

シナリオ 4: 難読化されたコード構文を利用する

ユースケースの概要 圧縮された GPT ライブラリ コードの正確な構文に依存していると、ほぼ間違いなく破損が発生します。Google は継続的な改善に向けて GPT の内部動作を常に変更しています。使用は API リファレンス ガイドに記載されている API に限定してください。
たとえば、一般的な要件は、PubAdsService が完全に読み込まれたタイミングを検出して refresh() を呼び出すことです。
エラーのあるコード スニペットの例
// Incorrect: Relying on an obfuscated property.
if (googletag.pubads().a != null) {
 functionProcessingGPT();
}
おすすめのエラーの修正方法
// Correct: Relying on public GPT API methods
// (i.e. googletag.pubadsReady in this case).
if(window.googletag && googletag.pubadsReady) {
 functionProcessingGPT();
}
修正の説明 / 説明 公開 API のみを使用できます。PubAdsService が完全に読み込まれているかどうかを検出する場合は、ブール値 googletag.pubadsReady を使用します。

シナリオ 5: GPT の関数や変数を上書きする

ユースケースの概要 GPT で使用される関数や変数の上書きに基づくユースケースは、サポートされていないユースケースのため、今後使用できなくなる可能性があります。GPT 内部のタイミングを変更すると、破損により、この種の不正な動作が表示される場合があります。
エラーのあるコード スニペットの例
// Incorrect: Haphazardly overwriting a googletag.* property.
googletag.cmd = [];
おすすめのエラーの修正方法
// Correct: Never overwrite googletag.* properties if they already exist.
// Always check before assigning to them.
googletag.cmd = googletag.cmd || [];

シナリオ 6: GPT の呼び出しの順序が間違っている

ユースケースの概要 GPT の内部が進化するにつれ、競合状態によって破損が生じる可能性があります。実行タイミングが理由で機能していた、順序が誤っているステートメントのセットは、その後は動作しなくなる可能性があります。
エラーのあるコード スニペットの例
// Incorrect: Setting page-level key-value targeting after calling
// googletag.enableServices().
googletag.enableServices();
googletag.defineSlot(...);
googletag.pubads().setTargeting(e, a);
おすすめのエラーの修正方法
// Correct: Setting page-level key-value targeting before calling
// googletag.enableServices().
googletag.pubads().setTargeting(e, a);
googletag.defineSlot(...);
googletag.enableServices();
修正の説明 / 説明 GPT の通常のタイミングを守って、競合状態を回避してください。有効な部分的な順序付けの例を次に示します。
  • 定義 - 有効化 - 表示
    1. ページレベルの設定を定義する
    2. スロットを定義する
    3. enableServices()
    4. ディスプレイ スロット
  • Enable-Define-Display
    1. ページレベルの設定を定義する
    2. enableServices()
    3. スロットを定義する
    4. ディスプレイ スロット

シナリオ 7: クロージャと JavaScript 変数スコープの不適切な使用

ユースケースの概要 JavaScript 変数のスコープ設定と、googletag.cmd.push に渡された関数でキャプチャした変数の値に関する誤った想定。
エラーのあるコード スニペットの例
// Incorrect: Variable x is declared outside the anonymous function
// but referenced within it.
for (var x = 0; x < slotCount; x++) {
 window.googletag.cmd.push(
  function(){
    // If GPT is not yet loaded, this code will be executed subsequently when
    // the command queue is processed. Every queued function will use the last value
    // assigned to x (most likely slotCount).
    // This is because the function closure captures the reference to x,
    // not the current value of x.
    window.googletag.display(slot[x]);
  })
 }
}
おすすめのエラーの修正方法
window.googletag.cmd.push(
 function(){
  // Correct: We both declare and reference x inside the context of the function.
  for (var x = 0; x < slotCount; x++){
   window.googletag.display(slot[x]);
  }
 }
)
修正の説明 / 説明

JavaScript では、クロージャは値ではなく参照によって変数をキャプチャします。つまり、変数が再代入された場合、その変数をキャプチャした関数クロージャが後で実行されたときに、新しい値が使用されます。したがって、コールバックが直ちに実行されるか遅延されるかによって、クロージャ内のコードの動作が変わる可能性があります。

非同期で読み込まれる GPT の場合は、コマンドキューのコールバックが GPT が読み込む速度によって、すぐに実行されるかどうかが決まります。上記の例では、キューに追加されたコマンドの動作が変わります。

問題を回避するには、コマンドキューに配置された関数がすぐに実行されることを想定せずにコードを記述する必要があります。また、JavaScript のスコープ設定ルールに注意する必要があります。

シナリオ 8: display の呼び出し後に DOM 内でスロット コンテナを移動する

ユースケースの概要 display の呼び出し後に DOM でスロット コンテナを移動したり挿入したりすると、GPT で望ましくないリフローや予期しない動作が発生する可能性があります。
エラーのあるコード スニペットの例
// Incorrect: Moving slot containers after calling display
googletag.defineSlot("/1234/travel/asia", [728, 90], "div-gpt-ad-123456789-0");
googletag.enableServices();
googletag.display("div-gpt-ad-123456789-0");
...
// Inserting another element before the slot container, pushing the slot container down the page.
document.body.insertBefore(someOtherElement, document.getElementById("div-gpt-ad-123456789-0"));
おすすめのエラーの修正方法
// Correct: Make any DOM order changes before calling display

document.body.insertBefore(someOtherElement, document.getElementById("div-gpt-ad-123456789-0"));
...
googletag.defineSlot("/1234/travel/asia", [728, 90], "div-gpt-ad-123456789-0");
googletag.enableServices();
googletag.display("div-gpt-ad-123456789-0");