Скрипт А/Б тестирования и ротации рекламы

Автор: webmasta | Опубликовано:
Обновлено:
скрипт для а/б тестирования

А/Б тесты нужны, А/Б тесты важны.

Что такое А/Б тестирование и ротация рекламы?

А/Б тестирование - это процесс определения лучшего варианта, путём сравнения разных гипотез.

Тестировать можно не только рекламу, но вообще всё, что угодно: цвет кнопок, описания, расположение элементов на сайте (левый/правый сайдбар) и тд.

Ротация рекламы - это показ разных видов, форм, размеров рекламных блоков. Например видео или баннерная реклама, размер блока 240х400 или 300х600, цвет ссылок красненьким или синеньким, шрифт 12 или 16 размера и тд.

В этом материале я коснусь самого простейшего варианта - тестирование рекламных сетей и различных форматов, которые они предоставляют.

Почему это важно и зачем это надо?

Как из огромного множества рекламных сетей и парнёрских программ выбрать именно ту, которая будет приносить максимальный доход на сайте?

Большинство вешают рекламу одной партнёрки на неделю, затем меняют коды и ставят рекламу от других и так по кругу.

Почему это плохой вариант:

  • Трафик не постоянен.
  • Рекламодатели не постоянны: уходят и приходят, бюджеты перераспределяются, бизнесы закрываются и открываются.
  • Меняются сезоны, интересы и настроение пользователей, их намерения штормит.
  • Синусоида на графике посещаемости -  количество посетителей постоянно скачет вверх-вниз.
    • Можно словить хайп на событийном трафике или наоборот провалиться вниз и не понять объективную картину.
  • Если вешать блоки вручную, скорее всего количество показов будет разным у каждой из сетей.

Другими словами, в любых тестах должны быть максимально одинаковые условия, чтобы результаты не были искажены.

Поэтому рекламу надо тестировать здесь и сейчас на одинаковом трафике с максимально честным распределением показов по ровну между участниками тестирования. Только тогда соберете достоверные и объективные данные, на основе которых можно сделать выводы о прибыльности.

Какие есть варианты?

Вручную, как я объяснил выше, самый плохой способ тестирования.

Поэтому рассмотрим решения получше:

  1. Системы управления рекламой, например AdFox, AdRiver или аналоги. Минус тут жирнющий - проще научиться управлять космическим кораблём и попасть в миссию по колонизации Марса к Илону Маску, чем хоть что-то понять без бухла в том же адфоксе.
     
  2. Сторонние скрипты или фреймворки - часто тяжеловесны и всё так же требуют времени на изучение и установку. И не факт, что оно Вам надо.
     
  3. Простой самописный скрипт - свою работу по сравнению "здесь-и-сейчас" выполнит.

Каждый способ имеет и плюсы и минусы.

Если работаем с крупным порталом, то однозначно нужен маркетолог или какой-то отдел продаж, который в Адфоксе будет откручивать рекламу.

Для средних и малых сайтов, мамкиных вебмастеров и прочих ремесленников подойдёт и маленький скрипт.

Что должен делать скрипт?

В моей голове сложились следующие критерии:

  1. Должен равномерно распределять показы.
  2. Не показывать подряд одну и ту же рекламу одному посетителю.
  3. Быстро загружаться на нативном JS без использования сторонних библиотек.
  4. Быть лёгким и гибким в использовании.
  5. Возможность одновременного тестирования блоков в разных частях сайта.
  6. Работать с неограниченным количеством вариантов. Например я хочу потестировать 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>

В месте вызова этого кода будет вставлена ротация рекламы.

Здесь сначала создаём массив, каждый объект которого имеет два элемента:

  1. html - не скриптовая часть рекламного кода, всякие div и прочий HTML код,
  2. script - скрипт вызова, всё, что внутри блока <script></script> рекламного кода.

Если не указывать html или script - они не будут выводиться. Можно вывести только HTML код, если, например надо показать свой простой баннер с картинкой-ссылкой. Или наоборот вывести только JS какой-то сети. Но что-то одно указать надо, чтобы был хоть какой-то вывод.

Пример

Если сложно, то далее приведу пример вставки кода РСЯ.

У него есть две части кода:

  1. то, что вставляется в шапку сайта
  2. и код самого баннера, который, в свою очередь, тоже можно условно на две части поделить - 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>

Таких вызовов можно сделать сколько угодно.

Главное правило - название объекта (массива) с рекламными блоками и зоны, в которой они отображаются, должны быть уникальными для каждого места.

  1. Далее скрипт смотрит, не существует ли уже кука с названием rotator_<название зоны>, например rotator_header.
  2. Эта кука хранит индекс (порядковый номер) рекламы из массива.
    • Если кука существует и в её значении присутсвтует индекс - скрипт берёт СЛЕДУЮЩИЙ код из массива рекламы и перезаписывает куку с новым значением.
    • Если куки нет - берём РАНДОМНЫЙ код рекламы и пишем куку.
    • Если достигнута последняя реклама из списка - идём по кругу и берём опять первую.
    • Кука хранится сутки (86400 секунд) после последнего вызова рекламы.

Использование cookie гарантирует, что каждый пользователь не будет подряд видеть одну и ту же рекламу.

Нарушает ли скрипт правила рекламных сетей?

В каждой партнёрке всегда написано: изменение кода рекламных блоков запрещено.

Но так как скрипт НЕ меняет сам код, а меняет лишь способ его вызова, то никаких нарушений тут нет.

    Минусы такой реализации

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

    Чем больше глубина просмтора на сайте, тем "честней" будет распределение показов.

    Если пользователи совершают 1 просмотр и уходят, то:

    1. это не значит, что сайт плохой, возможно они быстро получают, что хотели,
    2. а первый показ рекламы будет случайным.

    Другие минусы:

    • Нет распределения показов.
    • Нет сегментации аудитории.
    • Нет сбора статистики показов. Есть только статистика, которую предлагают используемые партнёрки.

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

    Да, способ не идеальный, есть куда стремиться и пока писал материал родилось несколько новых идей. Но как относительно простой способ А/Б тестов - пойдёт.

    Добавить комментарий

    Ограниченный HTML

    • Допустимые HTML-теги: <a href> <b> <i>
    • Строки и абзацы переносятся автоматически.
    • Адреса веб-страниц и email-адреса преобразовываются в ссылки автоматически.