Привет друзья! Абсолютно все создаваемые сайты я стараюсь доводить до идеальных показателей. После верстки дизайна, обязательно проверяю валидность кода, адаптирую под мобильные устройства. После «натяжки» и установке на wordpress отключаю генерируемые скрипты, в которых нет необходимости и подключаю библиотеки в корневом каталоге сайта.
Однако встречаются ситуации когда подключается код работающий на стороннем ресурсе. Из-за частых обновлений и модификаций скачивать его нет смысла, а воздействия данных скриптов сказывается на скорость загрузки сайта.
Самый распространенный вариант это коды счетчиков и рекламных баннеров.
Тут возникает вопрос как сделать чтобы PageSpeed не ругался на tag.js Янедек метрики и рекламу РСЯ.
Ответ лежит на поверхности. Загрузить скрипты после полной загрузки сайта.
Отложенная загрузка кода Яндекс.Метрики
В погоне за идеей решил посмотреть готовые варианты и благо они есть. Варианты реализации отложенной загрузи предлагают разные, например через таймер задержки setTimeout
или DOM-дерево DOMContentLoaded
.
Немного почитал ветки на форумах нарвался на статью с готовым и решением, а еще реализованным в виде плагина WordPress.
Ссылка на депозитарий плагина — https://wordpress.org/plugins/true-lazy-analytics/ поддерживает Google Analytics, Пиксель Facebook, Hotjar, Яндекс Метрика, Liveinternet.
Ссылка на статью — https://www.kobzarev.com/technical-seo/yandex-metrika-lazy-load/
Для уверенных в себе пользователей, автор предлагает код для вставке в functions.php
add_action( 'wp_footer', function() { ?> <script type="text/javascript"> ( function () { 'use strict'; // Флаг, что Метрика уже загрузилась. var loadedMetrica = false, // Ваш идентификатор сайта в Яндекс.Метрика. metricaId = 123456789, // Переменная для хранения таймера. timerId; // Для бота Яндекса грузим Метрику сразу без "отложки", // чтобы в панели Метрики были зелёные кружочки // при проверке корректности установки счётчика. if ( navigator.userAgent.indexOf( 'YandexMetrika' ) > -1 ) { loadMetrica(); } else { // Подключаем Метрику, если юзер начал скроллить. window.addEventListener( 'scroll', loadMetrica, {passive: true} ); // Подключаем Метрику, если юзер коснулся экрана. window.addEventListener( 'touchstart', loadMetrica ); // Подключаем Метрику, если юзер дернул мышкой. document.addEventListener( 'mouseenter', loadMetrica ); // Подключаем Метрику, если юзер кликнул мышкой. document.addEventListener( 'click', loadMetrica ); // Подключаем Метрику при полной загрузке DOM дерева, // с "отложкой" в 1 секунду через setTimeout, // если пользователь ничего вообще не делал (фоллбэк). document.addEventListener( 'DOMContentLoaded', loadFallback ); } function loadFallback() { timerId = setTimeout( loadMetrica, 1000 ); } function loadMetrica( e ) { // Пишем отладку в консоль браузера. if ( e && e.type ) { console.log( e.type ); } else { console.log( 'DOMContentLoaded' ); } // Если флаг загрузки Метрики отмечен, // то ничего более не делаем. if ( loadedMetrica ) { return; } (function(m,e,t,r,i,k,a){m[i]=m[i]||function(){(m[i].a=m[i].a||[]).push(arguments)}; m[i].l=1*new Date();k=e.createElement(t),a=e.getElementsByTagName(t)[0],k.async=1,k.src=r,a.parentNode.insertBefore(k,a)}) (window, document, "script", "https://cdn.jsdelivr.net/npm/yandex-metrica-watch/tag.js", "ym"); ym( metricaId, "init", { clickmap:true, trackLinks:true, accurateTrackBounce:true }); // Отмечаем флаг, что Метрика загрузилась, // чтобы не загружать её повторно при других // событиях пользователя и старте фоллбэка. loadedMetrica = true; // Очищаем таймер, чтобы избежать лишних утечек памяти. clearTimeout( timerId ); // Отключаем всех наших слушателей от всех событий, // чтобы избежать утечек памяти. window.removeEventListener( 'scroll', loadMetrica ); window.removeEventListener( 'touchstart', loadMetrica ); document.removeEventListener( 'mouseenter', loadMetrica ); document.removeEventListener( 'click', loadMetrica ); document.removeEventListener( 'DOMContentLoaded', loadFallback ); } } )() </script> <?php } );
Комментариев в коде достаточно, чтобы понять иерархические действия скрипта. Достаточно поменять идентификатор счетчика на свой.
Недостатком такого трюка может быть не большая погрешность в статистики отказов.
Отложенная загрузка рекламный блоков РСЯ
Вдохновившись идеей решил реализовать на JavaScript
отлаженную загрузку блоков рекламы.
По умолчанию код RTB для вставки на сайт состоит из двух частей:
Код загрузчика рекламы в <head>
<script>window.yaContextCb = window.yaContextCb || []</script> <script src="https://yandex.ru/ads/system/context.js" async></script>
Код рекламного блока
<div id="yandex_rtb_R-A-588461-2"></div> <script> window.yaContextCb.push(()=>{ Ya.Context.AdvManager.render({ renderTo: 'yandex_rtb_R-A-588461-2', blockId: 'R-A-588461-2' }) }) </script>
div с идентификационным номером вставляем в HTML-код вашего сайта между тегами <body>
и </body>
в том месте, где должен отображаться рекламный блок.
А содержимое тега <script></script>
заворачиваем в нашу конструкцию и помещаем ее в footer
сайта.
<script> var event_status = false; // Статус события (ещё не произошло) window.addEventListener("load", function() { // Страница загрузилась полностью ["mouseover", "click", "scroll"].forEach(function(event) { window.addEventListener(event, function() { // Произошло нужное событие (mouseover, click или scroll) с объектом window if(!event_status) { // ВАШ КОД window.yaContextCb.push(()=>{ Ya.Context.AdvManager.render({ renderTo: 'yandex_rtb_R-A-588461-2', blockId: 'R-A-588461-2' }) }) event_status = true; // Статус события (произошло) } }, { once: true }); }); }); </script>
Таким образом загрузка рекламных блоков на страницах сайта произойдет после выполнения условий: страница загружена полностью, человек совершил одно любое действие (движение курсора, клик, прокрутка).
Вот бы ещё добавить отложенный таймер, загрузить блоки рекламы через определённое количество секунд после загрузки страницы и выполнения действия. Что тут можно добавить в код?
Должно работать. Здесь мы использовали setTimeout(showAd, 5000) для задержки загрузки рекламного блока на 5 секунд, перед загрузкой блока мы вызываем event_status и используем API Яндекс.Директ для отображения контекстной рекламы.
Здравствуйте, я попробовал первый вариант отложенной загрузки по действию, но у меня 2 блока на странице, а загружается после действия мышкой только первый. Должно работать с несколькими блоками?
Здравствуйте. В количестве блоков ограничений нет. Блок который не подгружается «новоиспеченный»? если да, то попробуйте установить сначала без скрипта отложки. Возможно РСЯ не может полноценно проиндексировать страницу.
Спасибо, Антон!
А как реализовать подобное для рекламной сети MyTarget? У них такой код:
(MRGtag = window.MRGtag || []).push({})
Не уверен что будет работать, но попробуйте так:
Для вывода
А как это откладывание сказывается на монетизации?
По идее, может существенно уменьшиться количество показываемых баннеров…
По идее? нет! задача кода «ускорение загрузки сайта».
Если одно из действий не выполнено, то меня смущает трафик вашего сайта.
Здравствуйте, Антон!
А используете ли вы сами свой скрипт для отложенной загрузки именно Метрики? И не было ли каких-то сбоев или проблем со статистикой ? Или вы только для рекламных блоков используете ?
Здравствуйте. Использовал, проблем не заметил. Незначительное снижение показателя «Время на сайте», но нужно понимать, что это только по метрике