В погоне за зелеными показателями PageSpeed веб оптимизаторы тратят много времени. Как правило, рекомендации от pagespeed insights обоснованы, но не всегда разумны. Так или иначе бывают ситуации (например, требование заказчика), в которых необходимо добиться 100 из 100.

Отложенная загрузка кода Яндекс.Метрики и рекламных блоков РСЯ

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

Таким образом загрузка рекламных блоков на страницах сайта произойдет после выполнения условий: страница загружена полностью, человек совершил одно любое действие (движение курсора, клик, прокрутка).

Антон Воронцов

Вебмастер любитель, SEOшник самоучка.

В 2013 году попав в трудное финансовое положения, начал изучать различные способы заработка в интернете. С тех пор интернет стал для меня не только средством информации, но и источником дополнительного дохода.

Читаю много различной литературу и стараюсь быть в курсе всех трендов.

Основные интересы: финансы и инвестирование, сайтостроение, seo и smm продвижение.

Все статьи автора
10 комментариев

Не нашли ответа на свой вопрос? Задайте его в комментариях.

Если ответ найден, то просто отблагодари автрора добрым словом

  1. Илья
    14.04.2023 в 10:23

    Вот бы ещё добавить отложенный таймер, загрузить блоки рекламы через определённое количество секунд после загрузки страницы и выполнения действия. Что тут можно добавить в код?

    • Антон Воронцов
      30.04.2023 в 13:56
      // Загрузка рекламного блока при наступлении события с использованием таймера
      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) {
              // Событие произошло впервые
              setTimeout(showAd, 5000); // откладываем загрузку рекламного блока на 5 секунд
              // Исполняем код от Яндекса
              window.yaContextCb.push(() => {
                Ya.Context.AdvManager.render({
                  renderTo: 'yandex_rtb_R-A-588461-2',
                  blockId: 'R-A-588461-2'
                });
              });
              event_status = true; // Событие произошло
            }
          }, {
            once: true
          });
        });
      });
      

      Должно работать. Здесь мы использовали setTimeout(showAd, 5000) для задержки загрузки рекламного блока на 5 секунд, перед загрузкой блока мы вызываем event_status и используем API Яндекс.Директ для отображения контекстной рекламы.

  2. amoc
    15.06.2023 в 18:30

    Здравствуйте, я попробовал первый вариант отложенной загрузки по действию, но у меня 2 блока на странице, а загружается после действия мышкой только первый. Должно работать с несколькими блоками?

    • Антон Воронцов
      25.06.2023 в 20:57

      Здравствуйте. В количестве блоков ограничений нет. Блок который не подгружается «новоиспеченный»? если да, то попробуйте установить сначала без скрипта отложки. Возможно РСЯ не может полноценно проиндексировать страницу.

  3. Илья
    22.06.2023 в 19:58

    Спасибо, Антон!
    А как реализовать подобное для рекламной сети MyTarget? У них такой код:

    (MRGtag = window.MRGtag || []).push({})

    • Антон Воронцов
      25.06.2023 в 21:12

      Не уверен что будет работать, но попробуйте так:

      <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) {
                 
                              // ВАШ КОД
                              (MRGtag = window.MRGtag || []).push({})
                               
                              event_status = true; // Статус события (произошло)
                 
                          }
                         
                      }, {
                          once: true
                      });
                   
                  });
                 
              });
      </script>
      

      Для вывода

      <ins class="mrg-tag" data-ad-client="ad-***" data-ad-slot="***"></ins> 
      
  4. Андрей
    https://kinonavigator.ru/
    08.07.2023 в 23:31

    А как это откладывание сказывается на монетизации?

    По идее, может существенно уменьшиться количество показываемых баннеров…

    • Антон Воронцов
      11.07.2023 в 13:18

      По идее? нет! задача кода «ускорение загрузки сайта».

      загрузка рекламных блоков на страницах сайта произойдет после выполнения условий: страница загружена полностью, человек совершил одно любое действие (движение курсора, клик, прокрутка).

      Если одно из действий не выполнено, то меня смущает трафик вашего сайта.

  5. Akkmal
    28.07.2023 в 21:40

    Здравствуйте, Антон!

    А используете ли вы сами свой скрипт для отложенной загрузки именно Метрики? И не было ли каких-то сбоев или проблем со статистикой ? Или вы только для рекламных блоков используете ?

    • Антон Воронцов
      03.08.2023 в 10:57

      Здравствуйте. Использовал, проблем не заметил. Незначительное снижение показателя «Время на сайте», но нужно понимать, что это только по метрике

Добавить комментарий

Подтверждаю условия Пользовательского соглашения и даю согласие на обработку персональных данных, в соответствии с Федеральным законом от 27.07.2006 года №152-ФЗ