Доработка Adblock

Доработка Adblock

Стратегия

Итак, Адблок… Но здесь я буду говорить не столько о блокировке рекламы, сколько об оптимизации и правильном использовании этого интересного своей универсальностью дополнения. Не отношусь к тем, кого раздражает сама реклама — меня раздражает способ ее доставки.
Точнее, меня раздражает вот что:
— утяжеление страниц и усложнение процесса их загрузки, как следствие — замедление ее;
— рост трафика (в корпоративной среде);
— шпионские скрипты, сбор личной информации;
— когда при загруженном HTML документе я еще не вижу страницы из-за задержек с подгрузкой какой-то пакости с левых серверов;
— появление процесса plugin-container, кушающего память в объемах, соизмеримых с самим браузером.
Помимо, собственно, рекламы данные проблемы создают в не меньшем объеме различные счетчики и «социальные виджеты» (новое зло, о котором веб 1.0 не знал), ведь страницы даже без рекламы содержат несколько скриптов счетчиков, а для каждой кнопки типа «мне нравится» каждой соцсети грузится свой скрипт! Потому моя стратегия будет в корне отличаться от стратегии создателей стандартных подписок для Adblock:
1) главное — не устранить рекламу, цель — уменьшение времени загрузки страниц, потребления памяти, трафика и т.п. — оптимизация «от машины«, поэтому фокус внимания — на скрипты и флэш, а просто скрывать элементы директивой ## — интересно меньше всего,
2) принцип Парето-эффективности: 20% правил блокируют 80% нежелательного контента,
3) (следствие п.1) универсальные правила, насколько это возможно!
4) сайты, на которые я не хожу / неактуальные в Этой Стране — пусть себе содержат кучу нежелательного контента, я категорически не хочу, чтобы при запросе каждого элемента с часто посещаемого сайта мой центральный процессор пробегал по мегабайту правил, которые никогда не сработают (или сработают раз в год).

Исследование

Адблок (исследованию подверглась версия для firefox) представляет из себя упакованный xpi (не распаковывается при установке), весящий 786 кб. Большая часть из этого архива (468 кб в сжатом виде, 1,3 Мб в распакованном) приходится на локализации, которые (ненужные) легко удалить из xpi тем же 7-zip. (Забегая вперед: сокращения потребления памяти в результате этой процедуры обнаружено не было, так же не повлияла и распаковка аддона).

Правила блокировки хранятся в папке профиля ФФ, в подпапке adblockplus или аналогичной по названию аддона (прочие настройки аддона хранятся в стандартном «реестре настроек» браузера). Заглянув туда, я обнаружил 2 огромных файла — INI и CSS, вместе весящих около 1,8 Мб (это «открытие» и стало причиной настоящего исследования). Понятно, что даром такие объемы (особенно CSS!) не обойдутся, даже если бы наш браузер был написан на чистом ассемблере. Чтобы понять, насколько велик impact, были проведены замеры потребления памяти с последними, на момент написания статьи, версиями аддонов семейства Adblock.
Потребление памяти браузером Firefox 17.0.1 (в мегабайтах) с разными аддонами семейства Adblock

подписки 0 1(cnt) 3(ruad+easy,bitblock,cnt)
adblock lite 1.4.3
blank 58 58 68
yandex.ru 73 73 139
прирост 15 15 71
adblock edge 2.0.2
blank 56 57 119
yandex.ru 73 69 129
прирост 17 12 10
adblock plus 2.2.1
blank 56 57 116
yandex.ru 70 69 128
прирост 14 12 12

Что видно из таблицы (кроме того, что результаты, в целом, озадачивают): изначальные предположения об оптимизированности и легковесности, на практике подтверждаются с точностью до наоборот: самый обычный, мэйнстримовый Adblock plus оказывается самым экономным, а lite-версия, несмотря на своё название, потребляет памяти больше всех, и, кроме того, заметно замедляет прорисовку тяжелых страниц, вроде поиска изображений в Яндексе.
Почему так получается? Всё дело в версиях Adblock plus, явившихся основой альтернативных аддонов — все они более старые, а новые — лучше оптимизированы (нечасто встречающееся явление в мире ПО). В версиях 1.x использовался кэш правил в виде javascript-файла, это решение оказалось неудачным в плане производительности и от него отказались.

Заглянем внутрь XPI. В chrome/locale лежат локализации для всевозможных языков, упомянутые выше. Наибольший интерес представляет папка defaults. Модификацией файла prefs.js можно автоматизировать выставление Адблоку всех настроек что удобно при массовом развертывании. Синтаксис стандартный — как у настроек самого браузера. Рекомендуются следующие настройки:
pref("extensions.adblockplus.savestats", false); pref("extensions.adblockplus.subscriptions_exceptionscheckbox", false); pref("extensions.adblockplus.patternsbackups", 2); pref("extensions.adblockplus.hideContributeButton", true);
(Подробнее об этих и других параметрах в prefs.js читайте здесь: adblockplus.org/ru/preferences)
К сожалению, параметры аддона нельзя заранее задать в файле настроек самого браузера — при первой загрузке аддона, он перезаписывает все заранее заданные параметры на дефолтные.

Свои правила игры

Стандартные подписки не только тяжеловесны, они не блокируют тяжелые и злоупотребляющие шпионажем скрипты google analytics, которые есть практически на каждом сайте, а значит — вручную хоть одно правило, но придется писать. А если писать одно — то почему бы (зная рег. выражения) и не все?
Правила было удобно сгруппировать по темам: в случае нарушения юзабилити страниц легче локализовать проблему, отключая правила поблочно. В основу нижеприведенных списков легли как готовые подписки, так и собственные наработки в области «анти-баннерных» правил для Squid. Интерфейс Адблока позволяет копировать выделенные правила в виде текстовых строк и вставлять скопированный текст в виде правил.

custom

/rs[0-9]?\.mail\.ru/[bd]/
||radar.imgsmail.ru^
/images.rambler.ru/(n|upl)//
||rl0.ru$domain=~rambler.ru
||hhcdn.ru/nposter/*
||pics.top.rbc.ru/top_pics/v2/jslib/ch2.js
||pics.rbc.ru/js/api.js
|http://pics.rbc.ru/*/afm/img.gif?
||pics.rbc.ru/banners/*
||loadup.ru/*$third-party
||myuniques.ru^$third-party
||oskale.ru^$third-party
||partner.pladform.ru^$third-party
||ningme.ru/*video2*$third-party
||klonedaset.org^$third-party
||vmblock.net^$third-party
@@||adv.magna.ru/$script

counters

//count(er)?[\?\.]/
/counters?
/top100.*?
/xtcore.js
/xgemius.js
||counter.$third-party
||tns-counter.ru/V
||google-analytics.com/ga.js
||google-analytics.com/urchin.js
||google-analytics.com/__utm.gif?
||bs.yandex.ru/informer
||cdn.^$third-party
||kiks.yandex.
||mc.yandex.ru/watch/
||mc.yandex.ru/metrika/
||mc.yandex.ru/webvisor/
||yandex.ru/cycounter?*
/counter\.rambler\.ru//
||yabs.yandex.ru/count/
||an.yandex.ru^
||top-fwz1.mail.ru
||top$third-party
/cnt.$third-party
||i.bigmir.net/cnt/
||count.ru/c$third-party
||hit.gemius.pl
||c.bigmir.net^
||spylog.$third-party
||hotlog.$third-party
||openstat.net/$third-party
||web-visor.com/c.js
||b.scorecardresearch.com/$third-party
||atdmt.com/$third-party
||amung.us^$third-party
###counters

uni-banners

/\D(?:3[123][-_x]88|88[-_x]3[123])\D/$domain=~money.yandex.ru
/[.-/]1[26]0[-x_]600?[.-/]/
/[.-/]468[-x_][68]0[.-/]/
/[.-/]300[-x_]250[.-/]/
/[.-/]728[-x_]90[.-/]/
/200x300*.swf
/(200|468)_1\.swf/
/https?://ad[sv]?[0-9]?\./
//e?rle\.cgi/
||reklama.$script,subdocument,object
||advert$third-party
||banner$third-party
||adserv$third-party
||tizer$third-party
/informer^$third-party
||adserv$third-party
||pagead$third-party
/advert.
/[/_]banner\.js/
/pagead^$third-party
//ad[sv]?//
_banner^
/banner^
/banners^
/adriverBanner.js
/BannerHandler.js?*
||*ads.*/$third-party
/adfox.$script
^krutilka/$third-party
/insertSWF.js
##.b-banner
###left_ads
###top-ads
###bn-bot-wrap
/*popunder$third-party,script
^popunder$image,~image,popup

banners

||yabs.yandex.ru/resource/
||adriver.ru/$third-party
||googleadservices.com^$third-party
||autocontext.begun.ru/
||bn.adblender.ru
||doubleclick.net/$third-party
||directadvert.ru$third-party
||tbn.ru$third-party
||adwolf.$third-party
||dt00.net/$third-party
||goodadvert.ru/$third-party
||marketgid.com/$third-party
||luxup.ru/$third-party
||zorkabiz.ru/$third-party
||novoteka.ru/$third-party
||arbocontext.ru/$third-party
||videoclick.ru/$third-party
||looksmart.com/$third-party
||rorer.ru/$third-party
||mixmarket.biz/$third-party
||adonweb.ru/$third-party
||1100ad.com/$third-party
||b2bvideo.ru/js/video.js.php?
||molodejj.tv/$third-party
||richmedia.yimg.com/
||content.medialand.ru/*$third-party
||medialand.ru/*$third-party,~script
||magna.ru/fcgi/*$third-party
||engine.video-link.ru/$third-party
||videoclick.ru/$third-party
||videoclik.$third-party
||b.kavanga.ru/exp?*
||rotaban.ru^$third-party
||post.rmbn.ru^

anti-social

//icon?[_-](rss|facebook|twitter|gplus)[-.]/
/icons/facebook$domain=~facebook.com
/addthis_widget.
||api-public.addthis.com/url/shares.json
|http://userapi.com/js/api/
/rss.png
||facebook.com/widgets/like$third-party
||facebook.com/plugins/*.php?$third-party,subdocument
||*.ak.facebook.com/connect/*$subdocument
/facebook.gif|$domain=~facebook.com
||api.facebook.com^$third-party
||api.qip.ru$third-party
||connect.mail.ru^$third-party
||odnoklassniki.ru^$third-party,~stylesheet
||stg.odnoklassniki.ru/share/$third-party
||odnoklassniki.ru/dk?st.cmd=extOneClickLike
||connect.ok.ru/connect.js$third-party
||connect.facebook.net/*/all.js$third-party
||mystatus.skype.com^
||vkontakte.ru/widget_$domain=~vk.com
||vk.com/widget_$third-party
||vk.com/share.php?*$script,third-party
||vk.com/images/upload.gif|$domain=~vk.com
||userapi.com^$third-party,domain=~vk.com
||stg.odnoklassniki.ru/share/odkl_share.js$third-party
||plus.google.com/$subdocument,domain=~google.ru
||google.*/cse/brand?form=
||google.com/js/plusone.js$third-party
||platform.twitter.com/widgets.js$third-party
||yandex.st/share/$domain=~yandex.ru
/widget.js$third-party
/widgets.js$third-party
/share.js$third-party
||share.pluso.ru/$third-party
##.g_blank_likes
##.googleplus
##.g-plus
##.twitter
##.twitter-follow-button
~facebook.com###facebook
##.facebook
##.fb-like
##.vkontakte
##.yashare-auto-init
##.social
##.social-links
##.fb-like-box
##.gmt-social-buttons
##.post_share
##.share-button
##.share_block
##.sharebar
##.social-links
###social-media
##.socials
##.addthis_toolbox

Anti-Adblock

/blockblock*$script
/anti_ab.
/adb*_detector.
/*adblock$script,domain=~adblockplus.org

Группа custom — это правила для определенных сайтов и своего рода свалка для новых правил, создаваемых визуально через контекстное меню «Adblock plus: заблокировать изображение…»: новое правило, созданное таким путем, добавляется в первую по счету группу фильтров в конец списка.

Итак, всё это, казалось бы, немалое количество правил на деле превращается в INI и CSS, в сумме весящие всего 7,9 кб. Что примерно в 230 раз(!) меньше варианта с тремя подписками.

Возможна и «ленивая» реализация этой стратегии: добавляется стандартная подписка против счетчиков ruadlist.googlecode.com/svn/trunk/cntblock.txt — весит скромные 12 кб и, что хорошо, обновляется разработчиком, и пишется несколько правил вручную: против google analytics, несколько универсальных правил против баннеров и против 1-2 самых распространенных скриптов соцсетей:

пример добавляемых вручную правил

В сети организации возможно создание собственной подписки. Это несложно: берется результирующий patterns.ini из папки adblockplus, в нем содержимое каждой секции [Subscription filters] выкладывается на веб-сервер в виде отдельного TXT файла с заголовком [Adblock Plus 2.0] в первой строке. Автоматически подключить свои подписки можно, например, подложив patterns.ini в папку adblockplus на каждой машине.

Справка на русском по синтаксису правил для Adblock Plus

Скачать patterns.ini с приведенными выше правилами