На радаре Search Engine Land Сущности и AI в SEO: как объединить контент и SEO-команды

Core Web Vitals

Оптимизировать CLS (Cumulative Layout Shift)

Критично

Зачем оптимизировать CLS

CLS (Cumulative Layout Shift) измеряет визуальную стабильность страницы: насколько сильно элементы сдвигаются во время загрузки и взаимодействия. Вы наверняка сталкивались с ситуацией — начинаете читать текст, а он внезапно прыгает вниз из-за подгрузившегося баннера. Или нажимаете кнопку «Отправить», а вместо неё попадаете на рекламу, потому что контент сместился. Именно это и измеряет CLS.

Google считает CLS одним из трёх Core Web Vitals. Целевое значение — меньше 0,1. Всё, что выше 0,25, — критическая проблема. По моей практике, CLS — самая коварная метрика: сайт может загружаться быстро, но раздражать пользователей постоянными скачками контента. И это бьёт по поведенческим факторам сильнее, чем медленная загрузка: пользователь не просто ждёт, а получает негативный опыт в момент взаимодействия.

Целевые значения CLS

  • Хорошо: до 0,1 — страница визуально стабильна, элементы не прыгают
  • Требует улучшения: 0,1-0,25 — заметные сдвиги, нужна оптимизация
  • Плохо: больше 0,25 — критические сдвиги, прямое влияние на ранжирование и конверсию

Пошаговая инструкция: как найти и устранить сдвиги

Шаг 1. Измерьте текущий CLS

Откройте PageSpeed Insights и проверьте страницу. В секции полевых данных найдите значение CLS — именно эти данные учитывает Google для ранжирования. Затем посмотрите лабораторные данные Lighthouse: в секции «Avoid large layout shifts» перечислены конкретные элементы, вызывающие сдвиги.

Важный нюанс: CLS считается не только при загрузке страницы, но и за весь период взаимодействия — включая скролл и клики. Сдвиг от lazy-loaded изображения на третьем экране, от появления cookie-баннера после скролла, от раскрытия аккордеона — всё это учитывается.

Шаг 2. Найдите проблемные элементы через Chrome DevTools

Откройте DevTools (F12), перейдите на вкладку Performance и запишите загрузку страницы с включённой галочкой «Screenshots». После записи найдите события Layout Shift на таймлайне — они отмечены красными маркерами. Кликните на каждый сдвиг: внизу увидите, какой именно элемент сместился, из какой позиции в какую и на сколько это повлияло на общий CLS.

Для отлова сдвигов при взаимодействии (не при загрузке) используйте расширение Web Vitals для Chrome. Включите режим Console Logging в настройках расширения. В консоли DevTools будут появляться подробные записи о каждом Layout Shift с указанием элемента и его вклада в общий CLS. Это особенно полезно для поиска сдвигов, которые происходят при скролле или клике.

Шаг 3. Проверьте данные в Search Console

Откройте отчёт «Основные интернет-показатели» в Google Search Console. Страницы с плохим CLS группируются по шаблону — если проблема в конкретном типе страниц (например, все статьи блога), можно исправить шаблон один раз и решить проблему для всех затронутых URL.

Шаг 4. Устраните причины сдвигов

После того как проблемные элементы определены, переходите к исправлению. Ниже разберу самые частые причины CLS и конкретные CSS-решения для каждой.

Основные причины CLS и способы исправления

Изображения и видео без указанных размеров

Это причина номер один для большинства сайтов. Когда браузер загружает изображение без атрибутов width и height, он не знает заранее, сколько места выделить. Сначала отрисовывает контент вокруг, а когда картинка загрузится — раздвигает макет, и всё ниже прыгает вниз.

Решение 1: атрибуты width и height в HTML. Всегда указывайте размеры в теге img:

<img src="photo.webp" width="800" height="450" alt="Описание">

Браузер использует эти значения для расчёта aspect ratio и резервирует место до загрузки изображения. Для адаптивного дизайна добавьте в CSS:

img {
  max-width: 100%;
  height: auto;
}

Изображение будет уменьшаться пропорционально в контейнере, но место под него будет зарезервировано заранее.

Решение 2: CSS-свойство aspect-ratio. Современный и более гибкий способ:

.hero-image {
  aspect-ratio: 16 / 9;
  width: 100%;
  object-fit: cover;
}

.product-thumb {
  aspect-ratio: 1 / 1;
  width: 100%;
  object-fit: contain;
}

Свойство aspect-ratio резервирует место нужной пропорции до загрузки изображения. Не нужно знать точные размеры в пикселях — достаточно пропорции. Работает во всех современных браузерах.

Для видео и iframe (YouTube, Vimeo) проблема аналогичная. Обёртка с aspect-ratio решает её:

.video-wrapper {
  aspect-ratio: 16 / 9;
  width: 100%;
}

.video-wrapper iframe {
  width: 100%;
  height: 100%;
}

Динамически подгружаемый контент

Рекламные блоки, баннеры, виджеты отзывов, формы подписки, блоки «Похожие товары» — всё, что загружается после основного контента и вставляется в поток документа, вызывает сдвиги. Решение: зарезервируйте фиксированное пространство.

/* Контейнер для рекламного блока 300x250 */
.ad-slot-sidebar {
  min-height: 250px;
  min-width: 300px;
  background-color: #f5f5f5; /* Плейсхолдер, чтобы не было пустоты */
}

/* Контейнер для баннера на всю ширину */
.banner-slot {
  min-height: 90px;
  width: 100%;
}

/* Контейнер для виджета отзывов */
.reviews-widget {
  min-height: 400px;
}

Ключевое правило: если вы знаете размер динамического блока — задайте min-height контейнера. Контент ниже не будет прыгать при загрузке рекламы или виджета. Если точный размер неизвестен — задайте приблизительный min-height. Небольшое пустое пространство лучше, чем скачок контента.

Веб-шрифты и FOUT/FOIT

При загрузке кастомного шрифта текст сначала отображается системным шрифтом (или не отображается вообще), а затем перерисовывается. Метрики букв у системного и кастомного шрифта отличаются — текст меняет высоту, строки переносятся иначе, и всё ниже сдвигается. Это называется FOUT (Flash of Unstyled Text) и генерирует CLS.

Решение: font-display: swap с настроенным fallback.

@font-face {
  font-family: 'MyFont';
  src: url('myfont.woff2') format('woff2');
  font-display: swap;
}

/* Подобранный fallback с корректировкой метрик */
@font-face {
  font-family: 'MyFont Fallback';
  src: local('Arial');
  size-adjust: 105%;
  ascent-override: 90%;
  descent-override: 22%;
  line-gap-override: 0%;
}

Свойства size-adjust, ascent-override, descent-override и line-gap-override позволяют подогнать метрики fallback-шрифта под кастомный. Если системный шрифт рендерится с теми же метриками, что и кастомный — при переключении текст не прыгает, и CLS остаётся нулевым.

Для подбора точных значений используйте инструмент Fallback Font Generator — загрузите свой шрифт, и инструмент рассчитает коэффициенты для ближайшего системного аналога.

Cookie-баннеры и верхние уведомления

Плашки с согласием на cookies, верхние баннеры с акциями, уведомления о режиме работы — если они появляются после загрузки и сдвигают контент вниз, CLS растёт. Это одна из самых частых проблем.

Решение: позиционирование вне потока документа.

/* Cookie-баннер внизу экрана — не сдвигает контент */
.cookie-banner {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 1000;
}

/* Верхний промо-баннер — sticky, не сдвигает */
.promo-bar {
  position: sticky;
  top: 0;
  z-index: 999;
}

/* Или зарезервируйте место заранее */
.notification-slot {
  min-height: 48px; /* Высота уведомления */
}

Элементы с position: fixed и position: sticky не участвуют в потоке документа и не вызывают Layout Shift. Если же баннер должен быть частью потока — зарезервируйте под него место заранее через min-height, даже если он ещё не загрузился.

Табы, аккордеоны и раскрывающийся контент

Если при клике на таб или аккордеон контент меняет высоту — весь контент ниже сдвигается. Это считается Layout Shift, даже если сдвиг инициирован действием пользователя (в текущей версии алгоритма Google учитывает и такие сдвиги, если они происходят не в пределах 500 мс после взаимодействия).

Решение для табов:

/* Задайте фиксированную минимальную высоту */
.tab-content {
  min-height: 300px; /* Высота самого высокого таба */
}

/* Или используйте CSS Grid с фиксированной областью */
.tabs-container {
  display: grid;
  grid-template-rows: auto 1fr;
}

.tab-panel {
  grid-row: 2;
  grid-column: 1;
  min-height: 300px;
}

Решение для аккордеонов:

/* Анимация через max-height вместо height: auto */
.accordion-body {
  max-height: 0;
  overflow: hidden;
  transition: max-height 0.3s ease;
}

.accordion-item.active .accordion-body {
  max-height: 500px; /* Заведомо больше реального контента */
}

Ещё лучше: используйте CSS-свойство transform для анимации вместо изменения height или max-height. Трансформации не вызывают Layout Shift, потому что выполняются на уровне GPU и не влияют на поток документа.

Динамическая вставка элементов через JavaScript

Любой элемент, вставленный в DOM через JavaScript выше текущего видимого контента, вызывает сдвиг. Особенно часто это происходит с:

  • Баннерами, которые загружаются через рекламную сеть
  • Виджетами чатов, которые раздвигают макет при инициализации
  • Блоками «Недавно просмотренные», которые подгружаются через AJAX
  • Уведомлениями и toast-сообщениями

Правило: каждый динамически вставленный блок должен иметь placeholder с фиксированными размерами. Если размер заранее неизвестен — вставляйте контент ниже текущего viewport (ниже видимой области экрана) или используйте position: fixed/absolute, чтобы не влиять на поток документа.

Встроенные карты и iframe

Яндекс Карты, Google Maps, встроенные формы — все эти iframe загружаются медленно и раздвигают макет, если под них не зарезервировано место.

.map-container {
  aspect-ratio: 16 / 9;
  width: 100%;
  background-color: #e8e8e8;
}

.map-container iframe {
  width: 100%;
  height: 100%;
  border: 0;
}

Серый фон background-color показывает пользователю, что здесь будет контент, и предотвращает ощущение «пустоты» до загрузки карты.

Типичные ошибки

  • Тестировать CLS только при загрузке страницы. Google учитывает CLS за весь период взаимодействия — включая скролл, клики и любые действия пользователя. Сдвиг от lazy-loaded изображения на пятом экране тоже считается. Тестируйте страницу полностью: прокрутите до конца, покликайте по табам и аккордеонам.
  • Прятать проблему через overflow: hidden. Скрытие переполнения на body не решает проблему CLS — браузер всё равно фиксирует сдвиг элементов внутри видимой области. Нужно устранять причину, а не маскировать следствие.
  • Забывать про мобильную версию. На мобильных CLS часто хуже: экран меньше, и сдвиг на 50 пикселей визуально заметнее, чем на десктопе. Кроме того, на мобильных чаще появляются динамические элементы (sticky-хедер, промо-баннер), которые сдвигают контент. Тестируйте обязательно в мобильном режиме.
  • Добавлять контент через JavaScript без резервирования места. Каждый динамически вставленный блок без placeholder — потенциальный источник CLS. Это относится к рекламе, виджетам, отложенным блокам.
  • Игнорировать шрифты как источник CLS. Переключение с системного шрифта на кастомный — частая и незаметная причина сдвигов. Без корректировки метрик fallback-шрифта текст меняет высоту при загрузке шрифта, и весь контент ниже прыгает.
  • Не задавать размеры для img внутри CMS-контента. Если редактор WordPress вставляет изображения через WYSIWYG без width/height — каждая картинка в статье будет источником CLS. Убедитесь, что тема или плагин автоматически добавляют атрибуты размеров.

Что проверить в итоге

  • CLS в полевых данных PageSpeed Insights ниже 0,1 для мобильных и десктопных устройств.
  • В Search Console нет страниц со статусом «Плохо» по CLS.
  • Все изображения и видео имеют явно указанные width и height (или CSS aspect-ratio).
  • Рекламные блоки и динамический контент обёрнуты в контейнеры с min-height.
  • Шрифты используют font-display: swap с настроенным fallback (size-adjust, ascent-override).
  • Cookie-баннер и верхние уведомления не сдвигают контент (position: fixed или sticky).
  • При клике на табы и аккордеоны контент ниже не прыгает (задан min-height или используются трансформации).
  • Встроенные карты и iframe обёрнуты в контейнеры с aspect-ratio.
  • В Chrome DevTools (Performance → Layout Shifts) нет красных маркеров с высоким вкладом в CLS.
  • Мобильная версия проверена отдельно и CLS на ней не превышает 0,1.

Нужна помощь с внедрением?

Проведу аудит вашего сайта и внедрю рекомендации. Результат — чистая техническая база и план роста.

Обсудить проект

Кто ведёт проект

Александр Тригуб — частный SEO-маркетолог. В поисковом маркетинге с 2010 года, предприниматель с 2001-го. В SEO пришёл из собственного бизнеса — знаю, как устроены продажи не из учебников, а из собственной выручки и расходов.

  • Специализация: медицина, B2B, e-commerce и локальные услуги — ниши, где каждый лид стоит дорого.
  • Подтверждённый опыт: 1092 заказа на Kwork (рейтинг 4.9 / 5) — подтверждённые отзывы, без учёта прямых клиентов. Проверить отзывы.
  • Формат: работаю напрямую, один специалист на проект — без менеджеров и субподрядных цепочек.
  • Отчётность: KPI по лидам и деньгам. Ежемесячный план/факт, а не PDF на 50 страниц.
15+лет в маркетинге
728отзывов
4.9рейтинг
1092заказов на Kwork