Привет друзья! Абсолютно все создаваемые сайты я стараюсь доводить до идеальных показателей. После верстки дизайна, обязательно проверяю валидность кода, адаптирую под мобильные устройства. После «натяжки» и установке на 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 Яндекс.Директ для отображения контекстной рекламы.