Сегодня наличие баннера с предупреждением о сборе cookie-файлов — это не просто "хороший тон", а прямое требование законодательства, такого как ФЗ-152 и GDPR. Владельцы сайтов обязаны получать явное согласие пользователя до того, как начнут сбор любых данных.

И здесь возникает главная проблема: Яндекс Метрика (как и Google Analytics) для своей работы использует cookie.

Если вы просто вставили код Метрики в <head> своего сайта, у меня для вас плохие новости: вы уже нарушаете закон. Аналитика начинает работать и устанавливать cookie (_ym_uid и др.) еще до того, как пользователь успел нажать кнопку "Принять" на баннере.

В этой статье мы разберем, как "повесить" запуск Яндекс Метрики на cookie-баннер, чтобы:

  1. Соответствовать закону.
  2. Не получить штрафных санкций от Google Page Speed за медленную загрузку JS.

Часть 1. Почему Метрику нужно блокировать? (Юридическая сторона)

Ключевой принцип законов о персональных данных (ПДн) прост:


"Нет согласия — нет сбора данных"

Что считаетсся "сбором данных"?

  • Установка cookie-файлов.
  • Отправка любых идентификаторов (даже анонимных).
  • Запись сессии (Вебвизор).

Файл cookie _ym_uid, который Метрика создает при первом визите, является уникальным идентификатором пользователя. С точки зрения закона, это такие же персональные данные, как и имя или e-mail, поскольку позволяет однозначно выделить пользователя из общей массы.

Стандартная ошибка: Сайт загружается, в <head> сразу же срабатывает код Метрики, Вебвизор начинает запись, cookie установлены. Только после этого пользователь видит баннер. Это прямое нарушение.

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

Часть 2. Как это влияет на Google Page Speed? (Техническая сторона)

Google Page Speed Insights и Lighthouse крайне чувствительны к любым скриптам, блокирующим основной поток отрисовки страницы. Код Метрики, хоть и асинхронный, все равно:

  • Добавляет вес странице (загрузка tag.js).
  • Требует процессорного времени на инициализацию (JS execution).
  • Может негативно влиять на метрики TBT (Total Blocking Time) и LCP.

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

В этом и заключается наш "лайфхак". Мы будем использовать отложенную загрузку (lazy-loading), но не по прокрутке, а по действию пользователя (клику на баннере).

Что видит Google Page Speed:

Робот загружает страницу. Он видит легкий HTML, CSS и крошечный JS-скрипт для управления баннером. Тяжелого скрипта mc.yandex.ru/metrika/tag.js в коде нет. Он не блокирует отрисовку. В итоге — ваша оценка Page Speed остается высокой.

Что видит пользователь:

Пользователь видит баннер. Если он его игнорирует, Метрика так и не загружается. Если он нажимает "Принять", скрипт Метрики подгружается в фоне, уже после полной отрисовки страницы. Это не влияет на воспринимаемую скорость загрузки.

Часть 3. Практическая реализация: Код и логика

Нам понадобится три элемента: HTML-разметка баннера, немного CSS и Vanilla JS для управления логикой. Этот код можно добавить прямо в ваш footer.php или в main.js.

Шаг 1. HTML-разметка баннера

Добавьте этот код в конец вашего footer.php, перед закрывающим </body>.

<!-- Cookie Consent Banner --> <div id="cookie-banner" class="cookie-banner"> <p> Мы используем файлы cookie, чтобы улучшить ваш опыт. Нажимая "Принять", вы соглашаетесь с нашей <a href="/privacy-policy" target="_blank">Политикой конфиденциальности</a>. </p> <button id="cookie-accept-btn" class="cookie-btn">Принять</button> </div>

Шаг 2. CSS-стили

Добавьте эти стили в ваш output.css (или любой другой файл стилей).

.cookie-banner { position: fixed; bottom: 0; left: 0; width: 100%; background-color: #2d3748; /* Темный фон / color: #fff; padding: 20px; z-index: 1000; display: none; / Изначально скрыт */ flex-direction: column; align-items: center; text-align: center; box-shadow: 0 -2px 10px rgba(0,0,0,0.2); }

.cookie-banner p { margin: 0 0 15px 0; font-size: 14px; }

.cookie-banner a { color: #63b3ed; /* Синий для ссылки */ text-decoration: underline; }

.cookie-btn { background-color: #48bb78; /* Зеленая кнопка */ color: #fff; border: none; padding: 10px 25px; border-radius: 5px; cursor: pointer; font-weight: bold; }

/* Показываем баннер, если он нужен */ .cookie-banner.is-visible { display: flex; }

/* Медиа-запрос для десктопов */ @media (min-width: 768px) { .cookie-banner { flex-direction: row; justify-content: space-between; text-align: left; } .cookie-banner p { margin: 0 20px 0 0; } }

Шаг 3. JavaScript (Самое важное)

Этот скрипт управляет всей логикой.

// Ждем, пока весь DOM загрузится document.addEventListener('DOMContentLoaded', function() {

const banner = document.getElementById('cookie-banner');
const acceptBtn = document.getElementById('cookie-accept-btn');
const METRICA_ID = 90000000; // 👈 ВАШ ID МЕТРИКИ
const CONSENT_COOKIE_NAME = 'user_cookie_consent';

/**
 * Эта функция инициализирует Яндекс Метрику.
 * Она содержит стандартный код счетчика.
 */
function initYandexMetrica() {
    console.log('Metrica Init...'); // Для отладки
    (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();
    for (var j = 0; j < document.scripts.length; j++) {if (document.scripts[j].src === r) { return; }}
    k=e.createElement(t),a=e.getElementsByTagName(t)[0],k.async=1,k.src=r,a.parentNode.insertBefore(k,a)})
    (window, document, "script", "[https://mc.yandex.ru/metrika/tag.js](https://mc.yandex.ru/metrika/tag.js)", "ym");

    ym(METRICA_ID, "init", {
        clickmap:true,
        trackLinks:true,
        accurateTrackBounce:true,
        webvisor:true // Включаем Вебвизор только после согласия
    });
}

/**
 * Проверяем, дал ли пользователь согласие ранее.
 */
function checkConsent() {
    // Простой поиск cookie по имени
    const hasConsent = document.cookie.split(';').some((item) => item.trim().startsWith(CONSENT_COOKIE_NAME + '='));

    if (hasConsent) {
        // Если согласие уже есть, сразу грузим Метрику
        initYandexMetrica();
    } else {
        // Если согласия нет, показываем баннер
        banner.classList.add('is-visible');
    }
}

/**
 * Обработчик нажатия на кнопку "Принять".
 */
function onAccept() {
    // 1. Устанавливаем cookie о согласии (например, на 1 год)
    const d = new Date();
    d.setTime(d.getTime() + (365 * 24 * 60 * 60 * 1000));
    const expires = "expires=" + d.toUTCString();
    document.cookie = CONSENT_COOKIE_NAME + "=true; " + expires + "; path=/; SameSite=Lax";

    // 2. Прячем баннер
    banner.classList.remove('is-visible');

    // 3. (САМОЕ ГЛАВНОЕ) Инициализируем Метрику
    initYandexMetrica();
}

// Назначаем обработчик на кнопку
acceptBtn.addEventListener('click', onAccept);

// Запускаем проверку при загрузке страницы
checkConsent();
});

Заключение: Два зайца одним выстрелом

Используя этот метод, мы решаем обе задачи:

  1. Юридическая чистота: Метрика и Вебвизор не запускаются и не собирают данные до тех пор, пока пользователь не даст явное согласие, нажав кнопку.
  2. Высокая скорость (Google Page Speed): Изначальная загрузка страницы не содержит "тяжелого" JS-кода аналитики. Скрипт подгружается позже, по действию пользователя, что идеально с точки зрения метрик Core Web Vitals.

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