This post is also available in: Английский
В одной из предыдущих статей мы рассказывали о том, как настроить рекламный сервер OpenX для достижения максимальной производительности. Однако, скорость загрузки баннеров зависит не только от сервера. В этой статье мы хотели бы рассказать какие приемы можно использовать на стороне клиента, чтобы достичь той же цели.
Основная проблема с загрузкой баннеров на стороне клиента заключается в том, что баннерный код большинства рекламных систем, включая OpenX, чаще всего использует скрипты, непосредственно встроенные в страницу с помощью тега
1 | script |
, и функцию
1 | document.write |
. Все это приводит к тому, что баннерный код должен загрузиться и выполниться синхронно, то есть пока он не загрузится, остальные элементы страницы не будут показаны. Например, если ваш баннер находится в верхней части страницы, а рекламный сервер испытывает большую нагрузку и очень медленно отвечает на запросы, то вся страница, на которой находится баннер, будет загружаться с большой задержкой.
К счастью существует несколько вариантов решения этой проблемы. Самый простой — это загружать баннеры внутри
1 | IFRAME |
-а. Но этот вариант обладает рядом недостатков:
- Не поддерживаются такие форматы, как баннеры, изменяющие размер или оформление текущей страницы.
- Рекламный сервер не увидит реальный referrer страницы, которую просматривает пользователь.
- Не поддерживается анализ контекста страницы, на которой отображается баннер, что снижает релевантность рекламы.
Для того, чтобы исключить недостатки
1 | IFRAME |
-а и в то же время загружать баннеры асинхронно существует jQuery-плагин LazyLoad Ad. Он превращает синхронные вызовы рекламного кода в асинхронные, перехватывая функцию
1 | document.write |
. Кроме того, он реализует функциональность, позволяющую загружать не всю рекламу сразу, а только те баннеры, которые пользователь может увидеть в текущей части страницы. Примеры использования этого плагина совместно с кодом различных рекламных систем приведены на его сайте.
Здесь мы покажем пример того, как использовать плагин для асинхронной загрузки графических баннеров из OpenX. Обычно рекламный код выглядит так (в примере используются шаблоны Smarty для подстановки значений):
var m3_u = (location.protocol==‘https:‘?‘https://{$ad_base}/ajs.php‘:‘http://
{$ad_base}/ajs.php‘);
var m3_r = Math.floor(Math.random()*99999999999);
if (!document.MAX_used) document.MAX_used = ‘,‘;
document.write ("<scr"+"ipt type=’text/javascript’ src=’"+m3_u);
document.write ("?zoneid={$zone_id}");
document.write (‘&cb=‘ + m3_r);
if (document.MAX_used != ‘,‘) document.write ("&exclude=" +
document.MAX_used);
document.write (document.charset ? ‘&charset=‘+document.charset : (document.characterSet ? ‘&charset=‘+document.characterSet : »));
document.write ("&loc=" + escape(window.location));
if (document.referrer) document.write ("&referer=" +
escape(document.referrer));
if (document.context) document.write ("&context=" + escape(document.context));
if (document.mmm_fo) document.write ("&mmm_fo=1");
document.write ("‘><\/scr"+"ipt>");
//]]>—></script><noscript><a href=’http://{$ad_base}/ck.php?n=a1eaf622&
cb={math equation="rand(1,10000000)"}’ target=’_blank’><img src=’http://{$ad_base}/avw.php?zoneid={$zone_id}&cb={math equation="rand(1,10000000)"}&n=a1eaf622′ border=’0′ alt=» /></a></noscript>
Перед использованием этого кода совместно с плагином LazyLoad Ad внесем следующие изменения:
- Удаляем тег
1noscript
, так как при отсутствии поддержки скриптов в браузере реклама не загрузится в любом случае.
- Изменим код таким образом, чтобы функция
1document.write
вызывалась только один раз, так как в противном случае могут возникнуть проблемы с неполной вставкой рекламного кода в браузере Google Chrome.
- Заключим JavaScript-код внутри тега
1code
, как того требует плагин.
- Завернем получившийся рекламный код внутрь
1div
-а с классом
1lazyload_ad, чтобы потом использовать этот селектор для вызова плагина.
В итоге получится следующее:
<code type="text/javascript"><!—
var m3_u = (location.protocol==’https:’?’https://{$ad_base}/ajs.php’:’http://{$ad_base}/
ajs.php’);
var m3_r = Math.floor(Math.random()*99999999999);
if (!document.MAX_used) document.MAX_used = ‘,’;
document.write ("<scr"+"ipt type=’text/javascript’ src=’"+m3_u
+"?zoneid={$zone_id}"
+’&cb=’ + m3_r
+(document.MAX_used != ‘,’ ? "&exclude=" + document.MAX_used : »)
+(document.charset ? ‘&charset=’+document.charset : (document.characterSet ? ‘&charset=’+document.characterSet : »))
+"&loc=" + escape(window.location)
+(document.referrer ? "&referer=" + escape(document.referrer) : »)
+(document.context ? "&context=" + escape(document.context) : »)
+(document.mmm_fo ? "&mmm_fo=1" : »)
+"’><\/scr"+"ipt>");
//—>
</code>
</div>
Этот код необходимо вставить в нужные места вашей веб-страницы так же, как и обычный рекламный код. А в JavaScript-е страницы добавить следующий вызов:
$(‘.lazyload_ad‘).lazyLoadAd({
forceLoad: true
});
});
В ходе эксплуатации плагина был выявлен ряд проблем в его реализации:
- Упомянутая выше проблема с неполным выводом рекламного кода в браузере Google Chrome.
- Режим отложенной загрузки баннеров, включенный по-умолчанию, не работает корректно, поэтому его пришлось отключить с помощью опции
1forceLoad: true
.
- При загрузке страницы на медленном канале связи два баннера могут вставиться в одно и то же баннерное место. Эта проблема разработчиками пока не решена.
Видеореклама
С видеорекламой все обстоит немного иначе. В ней вся логика загрузки рекламных роликов и оверлеев реализуется внутри Flash-плеера, поэтому разработчик обязательно должен предусмотреть асинхронный режим загрузки рекламы без прерывания показа основного контента. При этом точки выхода на рекламу будут немного сдвинуты вперед относительно желаемых значений и пре-ролл может превратиться в мид-ролл, а загрузку пост-ролла придется инициировать до наступления конца воспроизведения контента. С точки зрения реализации в этом нет никаких проблем, но потребуется объяснить причины происходящего рекламодателям.
Обход рекламных фильтров
Существует еще одна проблема с загрузкой рекламы на стороне клиента, с которой сталкивается любой рекламодатель в сети, — это различные баннерорезалки, например AdBlock — одно из самых популярных расширений для Firefox. Они чаще всего фильтруют рекламу по URL, реже по стандартным для рекламы размерам изображений, но в любом случае их принцип работы основан на перехвате всех HTTP-запросов, отправляемых браузером пользователя. Что можно сделать в этом случае? Самое очевидное решение, если вы используете собственный рекламный сервер, — это изменить URL рекламных запросов на такой, который не засвечен ни в одном из списков URL, используемых для фильтрации. В качестве дальнейшего развития этого подхода, можно придумать хитрую схему с динамически меняющимися URL-ами или с адресами, имитирующими адреса полезного контента. Но в большинстве случаев опытному пользователю не составит большого труда добавить ваши необычные рекламные URL-ы в свой фильтр.
Другой способ обхода рекламных фильтров, который имеет большую эффективность, — это проксирование рекламных запросов внутри протокола RTMP. Для этого на стороне Adobe Flash Media Server-а потребуется включить специальный плагин, проксирующий взаимодействие между RTMP-клиентом и рекламным сервером. А на стороне клиента все рекламные запросы должны отправляться из Flash-плеера. Этот способ очень удобно использовать для загрузки видео-рекламы, но и загрузка обычных графических баннеров тоже может быть реализована, используя для взаимодействия с Flash внешний JavaScript-интерфейс. Насколько нам известно, сейчас не существует рекламных фильтров, которые способны фильтровать взаимодействие, происходящее внутри RTMP-потоков. Блокировка же протокола RTMP на уровне TCP-порта не даст результата, если по тому же RTMP передается полезный видеоконтент, или, если используется RTMPT, работающий по 80-му порту. Однако, и у этого способа есть свои недостатки: зависимость от Flash и от платного Adobe FMS, необходимость разрабатывать плагин для проксирования на стороне сервера и специальный Flash-объект на стороне клиента.