Как избежать распространенных ошибок внедрения

Следующие сценарии представляют некоторые из наиболее распространенных ошибок, наблюдаемых при внедрении GPT. Хотя может показаться, что такие реализации хорошо работают с текущей версией GPT, нет гарантии, что они будут работать так же и в будущем. В самых крайних случаях эти реализации могут привести к непредсказуемым сбоям в показе рекламы. Они считаются неподдерживаемыми реализациями.

Каждый сценарий включает предлагаемый подход к устранению указанной проблемы.

Обратите внимание, что этот список не представляет собой полностью исчерпывающий список потенциальных проблем, но, как ожидается, послужит полезным руководством для определения типов проблем, которые, возможно, потребуется решить.

Более того, в зависимости от вашей реализации вам может потребоваться поискать все места на вашем сайте, где могут потребоваться такие изменения.

Распространенные ошибки

Сценарий 1. Использование неофициальных копий библиотек JavaScript GPT.

Описание варианта использования высокого уровня Размещение 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 src="https://securepubads.g.doubleclick.net/tag/js/gpt.js" crossorigin="anonymous" async></script>
// Also correct, if using Limited Ads
<script src="https://pagead2.googlesyndication.com/tag/js/gpt.js" async></script>

Сценарий 2. Использование прослушивателей тегов скриптов gpt.js.

Описание варианта использования высокого уровня Предполагать, что GPT API готов к вызову при загрузке файла JavaScript gpt.js , неверно, поскольку некоторые части API предоставляются файлом pubads_impl.js . Поэтому полагаться каким-либо образом (включая фреймворки) на 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.

Описание варианта использования высокого уровня Поскольку API GPT может быть не готов при загрузке файла JavaScript gpt.js или при определении объекта googletag , проверка этого объекта на предмет доступности API GPT ненадежна.
Пример фрагмента кода с ошибкой
// 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();
}
Пояснение/описание исправления GPT заполнит логический флаг googletag.apiReady, как только API будет готов к вызову, чтобы вы могли делать надежные утверждения.

Сценарий 4: Использование запутанного синтаксиса кода

Описание варианта использования высокого уровня Если вы полагаетесь на точный синтаксис минимизированного кода библиотеки GPT, вы почти наверняка столкнетесь с поломками. Пожалуйста, ограничьте использование API, описанного в Справочном руководстве по API , поскольку мы постоянно меняем внутреннюю работу GPT для постоянных улучшений.
Например, общим требованием является определение момента полной загрузки 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. включитьСервисы()
    4. Слоты дисплея
  • Включить-Определить-Отображение
    1. Определите настройки на уровне страницы
    2. включитьСервисы()
    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. Перемещение контейнеров слотов внутри DOM после вызова display

Описание варианта использования высокого уровня Перемещение или вставка контейнеров слотов в DOM после вызова display может привести к нежелательной перекомпоновке и непредсказуемому поведению в 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");

Сценарий 9: Перезапись API браузера

Описание варианта использования высокого уровня Перезапись (так называемое исправление обезьян, полизаполнение) API браузера не поддерживается в GPT. Эта практика может неожиданным образом нарушить сторонние скрипты, такие как GPT.
Пример фрагмента кода с ошибкой
// Incorrect: Overwriting window.fetch
const { fetch: originalFetch } = window;
window.fetch = (...args) => {
 console.log('Fetching!');
 return originalFetch(resource, config);
};
Предлагаемые способы исправления ошибки
// Correct: Avoid making changes to browser APIs.
// If you need custom logic, consider leaving the browser API intact.
const myFetch = (...args) => {
  console.log('Fetching!');
  return window.fetch(...args);
}