Техническое SEO: доступ поисковика к сайту

CLS

CLS — самая большая вспышка неожиданных сдвигов вёрстки за жизнь страницы: окно 5 с, порог 0,1 на 75-м процентиле CrUX.

Кирилл Бабийчук · обновлено · 5 мин чтения

CLS (Cumulative Layout Shift) — величина самой большой вспышки неожиданных сдвигов вёрстки за жизнь страницы. Сдвиг — видимый элемент сменил стартовую позицию между двумя кадрами. Это не LCP (когда появился основной блок) и не отчёт CWV целиком. Метрика загрузки — соседний LCP. Как Search Console клеит группы и красит статус по худшей из трёх — Core Web Vitals. Хаб — техническое SEO.

Порог Search Central / CrUX на 75-м процентиле, мобильные отдельно от компьютера: ≤0,1 — «хорошо», ≤0,25 — «нужно увеличить скорость», >0,25 — «плохо». Ноль идеален, 0,1 выбран как достижимый: web.dev прямо пишет, что 0,05 режет эмбеды, высоту которых не знают до загрузки. INP — следующий H1. Яндекс CLS в кабинете не считает.

Что суммируют, а что выкидывают

С июня 2021 CLS — не сумма всех сдвигов за сессию. Для бесконечной ленты и SPA старое определение росло без потолка. Сейчас: session window — сдвиги с промежутком меньше 1 с, окно не длиннее 5 с; в метрику идёт окно с максимальной суммой. 70% origin на 75-м процентиле не должны были увидеть изменение, остальные — улучшение (оценка Chrome Speed Metrics на момент смены).

Событие Входит в CLS? Почему
Картинка без width/height, снизу уехал текст Да У текста сменилась стартовая позиция
Новый блок вставили в DOM, соседи на месте Нет Сдвиг только если уже видимые элементы поехали
Элемент сам вырос, start position тот же Нет Нестабильный — тот, у кого сменились top/left (в обычном письме)
Клик/тап/клавиша, сдвиг ≤500 мс Нет Флаг hadRecentInput; скролл, драг и pinch этим флагом не считаются
Анимация через transform: translate/scale Нет Не трогает layout; top/height — трогает
Рекламный iframe вырос после загрузки Да Типичный эмбед без зарезервированной высоты

Оценка одного кадра: impact fraction × distance fraction. Impact — доля вьюпорта, которую заняли нестабильные элементы в этом и предыдущем кадре вместе. Distance — наибольший сдвиг по горизонтали или вертикали, делённый на большую сторону вьюпорта. Пример из web.dev: блок на половину экрана уехал вниз на 25% высоты → 0,75 × 0,25 = 0,1875. Невидимая часть за краем экрана в impact не входит. Раньше считали только impact — крупные блоки с малым ходом штрафовали слишком сильно, поэтому добавили distance.

Где ловят в поле, а лаборатория молчит

Лаборатория (Lighthouse, PSI Diagnose) видит сдвиги на загрузке. Живой CLS длится всю жизнь вкладки: баннер согласия, подгрузка ленты, шрифт, который перерисовал fallback крупнее, виджет чата на 30-й секунде. Поэтому поле почти всегда не ниже лаборатории. Смотрят CrUX / отчёт Core Web Vitals за ~28 дней. Свой RUM — onCLS из web-vitals: сырой layout-shift не группирует окна, врёт на bfcache и не видит сдвиги в iframe, которые метрика учитывает.

Типичный шаблон витрины. Герой без размеров бьёт и CLS, и поздний LCP. Шрифт без size-adjust / близкого fallback сдвигает абзац после swap. Cookie-баннер вставляют в body сверху без резерва — вспышка на первом экране. Сторонний эмбед: резервируют min-height под финальный кадр, иначе 0,05–0,1 на одном виджете. После клика «показать ещё» место под ответ лучше открыть сразу (скелетон), а не ждать API: иначе это уже не hadRecentInput, если ответ пришёл позже 500 мс.

CLS в норме, когда 75% полевых визитов шаблона держат вспышку ≤0,1. Нулевая лаборатория на пустом кэше этого не доказывает.

Связка с первым HTML: если баннер и герой уже в ответе сервера с явными размерами, сдвигать нечего. Пустая оболочка CSR, в которую потом падают блоки, копит окна сдвигов на каждом fetch — соседний CSR и SSR. Page Experience как широкий сигнал — Page Experience. Если в Console группа красная по CLS на всём каталоге, правят шаблон, не один URL: постановка SEO-аудита сайта.

Ограничение. Нет доли сайтов РФ с CLS >0,25 — не выдумываем. Нет формулы «минус N позиций за 0,26». Не складывайте индекс скорости Яндекса (открытия в Яндекс Браузере с мобильной выдачи) с 0,1 Google. Устаревшие отчёты, которые суммируют все сдвиги без окна 5 с, с текущим кабинетом не сравнивают.

Частые вопросы

Почему лаборатория показывает 0, а в Search Console CLS красный?

Lighthouse видит загрузку. Полевой CLS копит вспышки за всю жизнь страницы: баннер, лента, шрифт, эмбед, чат. Смотрят 75-й процентиль CrUX по группе, не разовый прогон.

Сдвиг после клика пользователя тоже портит CLS?

Если вёрстка поехала в пределах 500 мс после тапа, клика или клавиши — нет, стоит hadRecentInput. Скролл и жест масштаба этим флагом не считаются. Ответ API через секунду после клика — уже неожиданный сдвиг, место под него резервируют сразу.

Новый блок внизу страницы увеличивает CLS?

Сам по себе нет. В метрику попадают уже видимые элементы, у которых сменилась стартовая позиция. Вставка «в конец», которая никого не двигает во вьюпорте, нулевая. Вставка «над» списком, из‑за которой карточки прыгают — да.

CLS и LCP лечат одним сжатием картинки?

Нет. Сжатие бьёт по времени загрузки LCP. CLS с картинки лечат зарезервированным местом: width/height или aspect-ratio в первом HTML. Можно починить сдвиг и оставить поздний герой — это разные метрики.