А/Б тесты нужны, А/Б тесты важны.
Что такое А/Б тестирование и ротация рекламы?
А/Б тестирование - это процесс определения лучшего варианта, путём сравнения разных гипотез.
Тестировать можно не только рекламу, но вообще всё, что угодно: цвет кнопок, описания, расположение элементов на сайте (левый/правый сайдбар) и тд.
Ротация рекламы - это показ разных видов, форм, размеров рекламных блоков. Например видео или баннерная реклама, размер блока 240х400 или 300х600, цвет ссылок красненьким или синеньким, шрифт 12 или 16 размера и тд.
В этом материале я коснусь самого простейшего варианта - тестирование рекламных сетей и различных форматов, которые они предоставляют.
Почему это важно и зачем это надо?
Как из огромного множества рекламных сетей и парнёрских программ выбрать именно ту, которая будет приносить максимальный доход на сайте?
Большинство вешают рекламу одной партнёрки на неделю, затем меняют коды и ставят рекламу от других и так по кругу.
Почему это плохой вариант:
- Трафик не постоянен.
- Рекламодатели не постоянны: уходят и приходят, бюджеты перераспределяются, бизнесы закрываются и открываются.
- Меняются сезоны, интересы и настроение пользователей, их намерения штормит.
- Синусоида на графике посещаемости - количество посетителей постоянно скачет вверх-вниз.
- Можно словить хайп на событийном трафике или наоборот провалиться вниз и не понять объективную картину.
- Если вешать блоки вручную, скорее всего количество показов будет разным у каждой из сетей.
Другими словами, в любых тестах должны быть максимально одинаковые условия, чтобы результаты не были искажены.
Поэтому рекламу надо тестировать здесь и сейчас на одинаковом трафике с максимально честным распределением показов по ровну между участниками тестирования. Только тогда соберете достоверные и объективные данные, на основе которых можно сделать выводы о прибыльности.
▲Какие есть варианты?
Вручную, как я объяснил выше, самый плохой способ тестирования.
Поэтому рассмотрим решения получше:
- Системы управления рекламой, например AdFox, AdRiver или аналоги. Минус тут жирнющий - проще научиться управлять космическим кораблём и попасть в миссию по колонизации Марса к Илону Маску, чем хоть что-то понять без бухла в том же адфоксе.
- Сторонние скрипты или фреймворки - часто тяжеловесны и всё так же требуют времени на изучение и установку. И не факт, что оно Вам надо.
- Простой самописный скрипт - свою работу по сравнению "здесь-и-сейчас" выполнит.
Каждый способ имеет и плюсы и минусы.
Если работаем с крупным порталом, то однозначно нужен маркетолог или какой-то отдел продаж, который в Адфоксе будет откручивать рекламу.
Для средних и малых сайтов, мамкиных вебмастеров и прочих ремесленников подойдёт и маленький скрипт.
▲Что должен делать скрипт?
В моей голове сложились следующие критерии:
- Должен равномерно распределять показы.
- Не показывать подряд одну и ту же рекламу одному посетителю.
- Быстро загружаться на нативном JS без использования сторонних библиотек.
- Быть лёгким и гибким в использовании.
- Возможность одновременного тестирования блоков в разных частях сайта.
- Работать с неограниченным количеством вариантов. Например я хочу потестировать 2, 5 или 10 разных форматов в одном месте - должно быть изи.
Гуглёж ничего хорошего, как обычно, не принёс, поэтому пришлось всё делать самому.
▲Код скрипта и инструкция
Код состоит из двух частей.
Первая - это обработчик, который необходимо вставить в шапку сайта внутри тегов <head></head>.
Дополнительную нагрузку скрипт вообще не создаёт.
<script>
function setCookie(name, value) {
document.cookie = name + '=' + value + '; path=/; max-age=86400';
}
function getRandomAd(ads, cookieName) {
const adIndex = Math.floor(Math.random() * ads.length);
setCookie(cookieName, adIndex);
return ads[adIndex];
}
function getNextAdIndex(adIndex, adsLength) {
console.log(adIndex, adIndex+1, (adIndex + 1) % adsLength);
return (adIndex + 1) % adsLength;
}
function getAdIndexFromCookie(cookieName, adsLength) {
const cookies = document.cookie.split('; ');
for (let i = 0; i < cookies.length; i++) {
const [name, value] = cookies[i].split('=');
if (name === cookieName) {
const adIndex = parseInt(value, 10);
if (!isNaN(adIndex) && adIndex < adsLength) {
return adIndex;
}
}
}
return null;
}
function rotator(ads, zone) {
const cookieName = `rotator_${zone}`;
const adsLength = ads.length;
const adIndex = getAdIndexFromCookie(cookieName, adsLength);
const nextAdIndex = adIndex === null ? null : getNextAdIndex(adIndex, adsLength);
const ad = nextAdIndex === null ? getRandomAd(ads, cookieName) : ads[nextAdIndex];
setCookie(cookieName, ads.indexOf(ad));
if (ad.html) {
document.write(ad.html);
}
if (ad.script) {
const adScript = document.createElement('script');
adScript.type = 'text/javascript';
adScript.textContent = ad.script;
document.currentScript.parentNode.appendChild(adScript);
}
}
</script>
Этот код можно пихнуть в отдельный файл, например rotator.js и подключить коротким вызовом.
Только в таком случае надо выкинуть из него открывающий и закрывающий теги <script></script>.
<head>
<script src="/path/to/folder/js/rotator.js" type="text/javascript"></script>
</head>
Где /path/to/folder/js/ - это путь до папки с файлом скрипта относительно корня сайта.
Вторая часть кода - в том месте, где хотим вызвать ротацию рекламного блока делаем вот такую вставку (естественно код рекламных баннеров надо заменить на Ваш):
<script>
const banners = [
{
html: '<!-- Yandex.RTB R-A-123456-10 --><div id="yandex_rtb_R-A-123456-10"></div>',
script: 'window.yaContextCb.push(()=>{Ya.Context.AdvManager.render({renderTo: "yandex_rtb_R-A-123456-10",blockId: "R-A-123456-10"})})'
},
{
html: '<div id="mp_custom_1234"></div>',
script: '(function(w, d, n, s, t) {w[n] = w[n] || [];w[n].push(function() {mp_banners("1234");});t = d.getElementsByTagName("script")[0];s = d.createElement("script");s.type = "text/javascript";s.src = "https://mpsuadv.ru/lib/custom/banners.js";s.async = true;t.parentNode.insertBefore(s, t);})(this, this.document, "mpsuRotator");'
}
];
rotator(banners, 'sidebar');
</script>
В месте вызова этого кода будет вставлена ротация рекламы.
Здесь сначала создаём массив, каждый объект которого имеет два элемента:
- html - не скриптовая часть рекламного кода, всякие div и прочий HTML код,
- script - скрипт вызова, всё, что внутри блока <script></script> рекламного кода.
Если не указывать html или script - они не будут выводиться. Можно вывести только HTML код, если, например надо показать свой простой баннер с картинкой-ссылкой. Или наоборот вывести только JS какой-то сети. Но что-то одно указать надо, чтобы был хоть какой-то вывод.
Пример
Если сложно, то далее приведу пример вставки кода РСЯ.
У него есть две части кода:
- то, что вставляется в шапку сайта
- и код самого баннера, который, в свою очередь, тоже можно условно на две части поделить - html и сам скрипт.
В шапку вставляем всё, как положено по инструкции без изменений.
Код баннера имеет следующий вид:
<!-- Yandex.RTB R-A-123456-10 -->
<div id="yandex_rtb_R-A-123456-10"></div>
<script>window.yaContextCb.push(()=>{
Ya.Context.AdvManager.render({
renderTo: 'yandex_rtb_R-A-123456-10',
blockId: 'R-A-123456-10'
})
})</script>
Разбиваем его на две части и записываем каждую в одну строку.
Важно! Одинарные кавычки необходимо переписать на двойные или экранировать символом \
HTML:
<!-- Yandex.RTB R-A-123456-10 --><div id="yandex_rtb_R-A-123456-10"></div>
Из скриптовой части надо выкинуть открывающий и закрывающий теги <script></script> и оставить только внутреннее содержимое:
window.yaContextCb.push(()=>{Ya.Context.AdvManager.render({renderTo: "yandex_rtb_R-A-123456-10",blockId: "R-A-123456-10"})})
Далее обе части записываем в массив, как в примере выше.
Массив может содержать неограниченное количество рекламных блоков. Добавляйте хоть 5, хоть 10. Будут крутиться для каждого пользователя по кругу. А первый вызов будет рандомной рекламой.
Пример пяти разных блоков и экранирование одинарных кавычек, о которых написал выше:
<script>
const blocks = [
{
html: '<div>1</div>',
},
{
html: '<div><a href="https://site.com"><img src="ad.jpg" alt="Реклама"></a></div>',
},
{
html: '<div>3</div>',
script: ''
},
{
script: 'alert(\'4!!!\');'
},
{
html: '<div>5</div>',
}
];
rotator(blocks, 'sidebar');
</script>
Пояснение работы скрипта
Точка входа - вызов функции rotator(blocks, 'sidebar').
- blocks - объект с рекламой,
- 'sidebar' - название "зоны" в которой будет отображаться реклама. Это условное обозначение.
Обе переменные можете обзывать, как угодно, но вторая обязательно в кавычках и без пробелов.
Чтобы вызвать несколько блоков с ротацией, надо изменить и сам её вызов.
Если хотите вызвать рекламу в шапке сайта, то код может быть примерно таким:
<script>
const headerBanners = [
{
html: '<!-- Yandex.RTB R-A-123456-10 --><div id="yandex_rtb_R-A-123456-10"></div>',
script: 'window.yaContextCb.push(()=>{Ya.Context.AdvManager.render({renderTo: "yandex_rtb_R-A-123456-10",blockId: "R-A-123456-10"})})'
},
{
html: '<div id="mp_custom_1234"></div>',
script: '(function(w, d, n, s, t) {w[n] = w[n] || [];w[n].push(function() {mp_banners("1234");});t = d.getElementsByTagName("script")[0];s = d.createElement("script");s.type = "text/javascript";s.src = "https://mpsuadv.ru/lib/custom/banners.js";s.async = true;t.parentNode.insertBefore(s, t);})(this, this.document, "mpsuRotator");'
}
];
rotator(headerBanners, 'header');
</script>
Таких вызовов можно сделать сколько угодно.
Главное правило - название объекта (массива) с рекламными блоками и зоны, в которой они отображаются, должны быть уникальными для каждого места.
- Далее скрипт смотрит, не существует ли уже кука с названием rotator_<название зоны>, например rotator_header.
- Эта кука хранит индекс (порядковый номер) рекламы из массива.
- Если кука существует и в её значении присутсвтует индекс - скрипт берёт СЛЕДУЮЩИЙ код из массива рекламы и перезаписывает куку с новым значением.
- Если куки нет - берём РАНДОМНЫЙ код рекламы и пишем куку.
- Если достигнута последняя реклама из списка - идём по кругу и берём опять первую.
- Кука хранится сутки (86400 секунд) после последнего вызова рекламы.
Использование cookie гарантирует, что каждый пользователь не будет подряд видеть одну и ту же рекламу.
▲Нарушает ли скрипт правила рекламных сетей?
В каждой партнёрке всегда написано: изменение кода рекламных блоков запрещено.
Но так как скрипт НЕ меняет сам код, а меняет лишь способ его вызова, то никаких нарушений тут нет.
Минусы такой реализации
Распределение первого показа рекламы между разными пользователями случайное. Но на длинных дистанциях это распределение будет стремиться к равным значениям, особенно если блоков в ротации не много.
Чем больше глубина просмтора на сайте, тем "честней" будет распределение показов.
Если пользователи совершают 1 просмотр и уходят, то:
- это не значит, что сайт плохой, возможно они быстро получают, что хотели,
- а первый показ рекламы будет случайным.
Другие минусы:
- Нет распределения показов.
- Нет сегментации аудитории.
- Нет сбора статистики показов. Есть только статистика, которую предлагают используемые партнёрки.
Своя статистика и автоматизация помогли бы следить за распределением показов. Но это уже пахнет не простеньким скриптом, а целой системой управления, что уже не вписывается в концепцию.
Да, способ не идеальный, есть куда стремиться и пока писал материал родилось несколько новых идей. Но как относительно простой способ А/Б тестов - пойдёт.
▲
Добавить комментарий