Верх страницы
Обложка к записи Отложенная загрузка кода Яндекс.Метрики
Время для прочтения: 0 мин. 56 сек.

Отложенная загрузка кода Яндекс.Метрики

В процессе оптимизации нескольких сотен сайтов и в погоне за зелёными попугаями Google PageSpeed выработал для себя сниппет для отложенной (Lazy Load) вставки кода Яндекс.Метрики.

Несмотря на то, что код Яндекс.Метрики недавно стал намного быстрее, Google PageSpeed всё равно ругает на него благим матом, поэтому попробуем решить данный вопрос.

Есть несколько способов отложить выполнение JavaScript на странице:

  • По счётчику через setTimeout
  • По событию загрузки DOM дерева DOMContentLoaded
  • По пользовательскому событию: scroll, touchstart, click, mouseenter

Попробуем объединить это всё это в одну кучу и посмотрим, что из этого выйдет.

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
	}
);

Данный сниппет можно вставить в functions.php вашей активной темы (дочерней темы) или создать новый плагин с данным кодом или создать mu-plugins, используя данный сниппет.

Для тех, кто не понимает, что тут происходит выше по коду, мы сделали простой и бесплатный плагин под WordPress для отложенной загрузки Яндекс.Метрики, Google Analytics и LiveInternet.

Автор: Кобзарёв Михаил

Русский разработчик с 20-ти летним стажем. Работаю с PHP, ООП, JavaScript, Git, WordPress, Битрикс, Joomla, Drupal, OpenCart, DLE, Laravel, Moonshine, Symfony, SuiteCRM.

Оптимизирую сайты под Google Page Speed, настраиваю импорты для больших магазинов на WooCommerce + WP All Import. Пишу плагины на заказ. Все мои услуги.

Веду блог о разработке, дайджест в телеграмме и в ВК.

Вы всегда можете нанять меня.

Комментарии
Подписаться
Уведомить о
guest

40 комментариев
Межтекстовые Отзывы
Посмотреть все комментарии
Anatoli Hotulev
Anatoli Hotulev
3 лет назад

Ссылка на «простой и бесплатный плагин» — битая. Исправьте пожалуйста.

Алексей Супрун
Алексей Супрун
3 лет назад

Спасибо огромное за статью! То, что доктор прописал 🙂

Последний раз редактировалось 3 лет назад Алексей Супрун ем
Алексей
Алексей
3 лет назад

После внедрения такого способа Метрика будет пропускать некоторые визиты и неправильно считать отказы

Последний раз редактировалось 3 лет назад Алексей ем
Андрей
Андрей
3 лет назад

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

Алексей
Алексей
2 лет назад

А есть такое же, но для вызова яндекс RTB (рекламной сети), она там в хедере хоть и висит async но сжирает с 95 до 50. ???

Михаил
Михаил
2 лет назад

На моем, не вордпресс, сайте метрика после вставки этого кода метрика перестала считать- все по нулям.
Код метрики (function(m,e,t,r,i,k,a) и далее отличается- заменил и его, но все равно счетчик не считает.

Михаил
Михаил
2 лет назад
Ответить на  Кобзарёв Михаил

Перед тегом </body>, где и стоял счетчик всегда вставил ваш код с заменой номера счетчика.

Утром, когда увидел нули на счетчике заменил кусок из вашего кода на код из самой метрики (номер счетчика здесь заменил на нули)

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

Михаил
Михаил
2 лет назад
Ответить на  Михаил

Причем, при такой установке, даже при просмотре кода страницы счетчика нет, при стандартной установке- есть

Михаил
Михаил
2 лет назад
Ответить на  Кобзарёв Михаил

Спасибо, Михаил

Счетчик заработал, но какого-то существенного роста pagespeed код не дал.

Михаил
Михаил
2 лет назад
Ответить на  Кобзарёв Михаил

Михаил, что посоветуете?
Сразу не заметил- в самом низу страницы, ниже подвала часть кода выводится
Если добавить <script type=»text/javascript» > после <!— Yandex.Metrika counter —> , то часть кода, не вся, пропадает, но и счетчик тоже метрика обнаружить не может.

Михаил
Михаил
2 лет назад
Ответить на  Михаил

Скрин

Скриншот 12-11-2022 104358.jpg
Михаил
Михаил
2 лет назад
Ответить на  Михаил

Кусок кода в начале у меня удален

add_action(
  'wp_footer',
  function() {
    ?>
    <script type="text/javascript">
mihdan
mihdan
2 лет назад
Ответить на  Михаил

Ну так оставьте

<script>Ваш код</script>
mihdan
mihdan
2 лет назад
Ответить на  Михаил

Почему код в одну строку? Комментарии при таком раскладе убивают весь JS

Михаил
Михаил
2 лет назад
Ответить на  mihdan

Михаил, спасибо огромное за код, разработчик моего сайта поставил его без ошибок- все стало побыстрее по pagespeed, на десктопе даже зазеленело, на смартах поскромнее, но тоже есть прибавка)

Скриншот 14-11-2022 123450.jpg
Ольга
Ольга
2 лет назад

А для opencart куда вставлять код не подскажите?

Антон
Антон
2 лет назад

Все работает как надо.
Но для PageSpeed Insights нужно выставить задержу 3000 в оригинале 1000, или подобрать значение для сайта индивидуально.
Минус задержки 3000 погрешность в статистике 1-3%.
Автор думаю стоит добавить в описание про данную настройку.

 // Подключаем Метрику при полной загрузке DOM дерева,
          // с «отложекой» в 1 секунду через setTimeout,
          
        }
  
        function loadFallback() {
          timerId = setTimeout( loadMetrica, 3000 );

Иван
Иван
1 год назад

Добрый день!
Код полностью рабочий!!
Вопрос? вот здесь….

if ( navigator.userAgent.indexOf( 'YandexMetrika' ) > -1 ) {

Как идет распознавание робота яндекс? Не совсем понял! Разжуйте, пожалуйста, очень, очень надо!!!

Александр
Александр
1 год назад
Ответить на  Кобзарёв Михаил

Здравствуйте! А можете сделать плагин для Dle 13.3 Пожалуйста

Илья
Илья
1 год назад

А как быть с вебвизором? Вставил код — помогло ускорить, а вот визор перестал работать.

Илья
Илья
1 год назад
Ответить на  Кобзарёв Михаил

Спасибо. попробуем! 🙂

Роман
Роман
1 год назад

Добрый день.
У меня эта строка появилась в хедере: <script async=»» src=»https://cdn.jsdelivr.net/npm/yandex-metrica-watch/tag.js»></script>
как перенести в подвал?

Viktor
Viktor
11 месяцев назад

Михаил,
Подскажите являются ли обязательным следующие части кода аналитики для сайта:

1)Yandex.Metrika
<noscript><div><img src=«https://mc.yandex.ru/watch/123456789» style=«position:absolute; left:-9999px;» alt=«» /></div></noscript>

2)rambler
<noscript><img src=«//counter.rambler.ru/top100.cnt?pid=1234567» alt=«Топ-100» /></noscript>

3) mail.ru
<noscript><div><img src=«https://top-fwz1.mail.ru/counter?id=1234567;js=na» style=«position:absolute;left:-9999px;» alt=«Top.Mail.Ru» /></div></noscript>

Я не знаю точно, но читал что это может быть для того что бы отслеживать посетителей у кого в браузере JS отключон, или это все же неверно и данный код можно просто не вставлять на сайт ?

Нужно ли вставлять этот код ?
Будут ли без него работать в нормальном режиме счетчики аналитики ?
в яндекс не писал, ответить сможете быстро ?

А.К.
А.К.
3 месяцев назад

Спасибо! Для метрики код рабочий. Маил.ру тоже запустился. А вот с гугл аналитикой и лайв интернет, не получается, не видят они они статистику. Их как-то по другому надо вставлять?
И ещё вопрос имеет ли смысл прописывать в данный скрипт defer или async=false чтобы в любом случае дать сначала загрузиться скриптам своего сайта и уже только потом счётчикам?

Viktor
Viktor
2 месяцев назад

Привет всем!

Хороший плагин однако чуть нехватает функционала.

Из плюсов:
1. Идеально подходит для сайтов локального бизнеса которые не используют точную аналитику для woocommerce.
2. Очень просто, установил, добавил скрипты и забыл

Из минусов:
1. Однажды помогал в Open Source проекте так случилось что ваделец противопоставил меня местной команде проекта и что бы я делал все по правилам эта команда выкатила изучть кучу страниц документации(6000стр) EN каким должен быть сайт GNU проектов, одно из правил было что бы сайт можно было разместить тор и Яндекс Метрика имеет спец функционал для эналитики такого сайта, а имеено нужно так же устанавливать
<noscript><div><img src=»https://mc.yandex.ru/watch/11111111″ style=»position:absolute; left:-9999px;» alt=»» /></div></noscript>
в плагине ранее это не поддерживалось, сейчас не смотрел

2. Так же не все хостинг провайдеры имеют хороший uptime и точность показателей веб аналитики меньше чем при использование GTM

3. При использование GTM у вас больше степень кастомизации и это проще чем править код плагина

4. Все скрипты в одном месте в GTM, часто вижу у тех кто использует плагин часть скриптов в плагине, часть через function.php добавлена

Предыдущая запись

Давайте дружить
в Telegram

Авторский блог вашего покорного слуги в Telegram про web, программирование, алгоритмы, инструменты разработчика, WordPress, Joomla, Opencart, Laravel, Moonshine, фильмы и сериалы