Cumulative layout shift: как найти и исправить CLS на телефоне

Cumulative layout shift на телефонах: пороги CLS 0,1 и 0,25, что сдвигается на мобильных и как найти причину в DevTools и по полевым данным.

Содержание

Cumulative layout shift (CLS) измеряет, насколько видимое содержимое неожиданно смещается, пока страница открыта; хороший показатель — 0,1 и меньше на 75-м процентиле визитов (web.dev, апрель 2023). Значения выше 0,25 считаются плохими. На телефонах обычно виноваты картинки без размеров, реклама и встраиваемые блоки без зарезервированного места, баннеры и уведомления о cookie, которые вставляются сверху, поздно загружающиеся веб-шрифты и анимации, меняющие раскладку. Найдите сместившийся элемент в DevTools и зарезервируйте для него место до загрузки.

Что такое cumulative layout shift

CLS — это самая большая серия сдвигов раскладки за время жизни страницы, а не сумма всех сдвигов. Каждый сдвиг оценивается как доля влияния, умноженная на долю расстояния. Доля влияния — часть области просмотра, которую занимают сместившиеся элементы, а доля расстояния — наибольшее расстояние, на которое сместился элемент, делённое на большую сторону области просмотра. Сдвиги с промежутком меньше секунды объединяются в окно сессии длиной не больше пяти секунд, и CLS равен окну с наибольшим значением (web.dev). Сдвиги, начавшиеся в течение 500 мс после действия пользователя, не учитываются (web.dev, Optimize CLS, февраль 2025).

Оценка CLS (p75)
Хорошо 0,1 или меньше
Нужно улучшить Больше 0,1 и до 0,25
Плохо Больше 0,25

Это пороги Google для «хорошего показателя», и web.dev рекомендует проверять 75-й процентиль отдельно для мобильных и для десктопа.

Почему на телефонах с CLS сложнее

Одно и то же смещение на маленьком экране получает больший балл, потому что обе доли считаются относительно области просмотра, а у телефона большая сторона меньше. Для иллюстрации по формуле выше: допустим, баннер cookie высотой 80 px появляется вверху страницы и сдвигает всё вниз, а область просмотра 390 × 844 px заполнена содержимым. Затронута почти вся площадь области просмотра, поэтому доля влияния около 1,0, а доля расстояния — 80 / 844 = 0,095. Итоговый балл около 0,095: до порога 0,1 не хватает ещё одного небольшого сдвига. Это иллюстрация, и в ней предполагается, что содержимое заполняет область просмотра.

Пример расчёта CLS: баннер высотой 80 px сдвигает контент на телефоне 390 × 844 px, получается 1,0 × 80/844 ≈ 0,095, чуть ниже границы хорошей оценки 0,1

Причины те же, что и на десктопе, только оцениваются на меньшей площади, а web.dev отмечает, что размеры рекламы могут различаться на разных устройствах, поэтому место, зарезервированное под десктопный размер, на телефоне может не подойти.

К тому же CLS измеряется не во всех браузерах. Библиотека web-vitals указывает onCLS() как работающую только в Chromium, тогда как остальные её функции работают и в Firefox, и в Safari (web-vitals README). В web-features 3.44.0 (октябрь 2026) Layout Instability API есть только в Chrome и Edge. Поэтому CLS, собранный в поле этой библиотекой, охватывает браузеры на Chromium, а визит из Safari на iPhone через неё CLS не сообщает.

Что сдвигается на мобильных и как это исправить

У каждой причины есть исправление, резервирующее место до появления содержимого. По руководству web.dev по оптимизации CLS (февраль 2025):

Причина Исправление
Изображения и видео без размеров Атрибуты width и height или CSS aspect-ratio
Реклама, встраиваемые блоки и iframe Зарезервируйте место через min-height или aspect-ratio; оставляйте заглушку, если реклама не пришла
Баннеры и уведомления о cookie, вставленные в страницу Зарезервируйте место заглушкой или показывайте поверх содержимого, чтобы страница не сдвигалась
Поздние веб-шрифты font-display: optional, близкий запасной шрифт, подгонка метрик запасного шрифта по размеру
Анимации Анимируйте transform вместо top, left или box-shadow

Изображения и видео

Задавайте собственный размер каждому изображению, чтобы браузер мог зарезервировать блок до прихода файла:

<img src="puppy.jpg" width="640" height="360" alt="Puppy with balloons">
img {
  height: auto;
  width: 100%;
}

Для адаптивных изображений web.dev советует сохранять одинаковые пропорции у всех вариантов srcset, а для <picture> указывать width и height на каждом <source> и на <img>. Новый формат изображений меняет только размер файла, поэтому эту проблему он не решает; схема с <picture> разобрана в статье WebP или AVIF. aspect-ratio входит в Baseline widely available с марта 2024 года (web-features 3.44.0).

Реклама, встраиваемые блоки и баннеры

Резервируйте место под слот по наименьшему ожидаемому размеру и используйте медиазапрос там, где на телефонах размер другой:

.ad-slot { min-height: 250px; }
@media (min-width: 768px) {
  .ad-slot { min-height: 90px; }
}

Две высоты здесь — примеры; берите свои размеры рекламы. Web.dev добавляет три совета: брать наименьший ожидаемый размер как минимум, показывать заглушку вместо схлопывания места, если реклама не пришла, и размещать поздно загружающееся содержимое ниже в области просмотра, потому что содержимое, вставленное у верхнего края, даёт большие сдвиги. Уведомление о cookie лучше сделать наложением или зарезервировать его высоту с первой отрисовки, а не сдвигать страницу вниз, когда скрипт решит его показать.

Веб-шрифты

И вспышка невидимого текста, и вспышка нестилизованного текста могут вызывать сдвиги, потому что невидимый текст всё равно размечается запасным шрифтом, как пишет web.dev. Там советуют font-display: optional и близкий запасной шрифт, подгонку метрик запасного шрифта по размеру и предзагрузку критичных шрифтов. Значения, предзагрузка и код запасного шрифта разобраны в руководстве по font-display swap.

Анимации и кнопка «Назад»

Анимируйте через transform: он не запускает пересчёт раскладки; web.dev отмечает, что композитные анимации translate в CLS не учитываются. Сделайте страницы пригодными и для кэша «назад/вперёд» (back/forward cache): восстановленная страница появляется такой, какой пользователь её оставил, и сдвигов из-за повторной загрузки нет. Первой загрузке это не помогает.

Как найти сдвиги раскладки

Лабораторные инструменты нужны, чтобы найти элемент, а полевые данные — чтобы понять, сталкиваются ли с ним реальные пользователи. Web.dev перечисляет такие пути:

  1. PageSpeed Insights: сравните полевой CLS (из Chrome UX Report) с лабораторным CLS из Lighthouse. Большой разрыв обычно указывает на сдвиги после загрузки, которых лабораторный запуск не видит.
  2. Lighthouse: его аудиты перечисляют сместившиеся элементы и их вклад, но часто показывают затронутый элемент, а не первопричину.
  3. Панель Performance в DevTools: запишите трассировку и откройте дорожку Layout shifts. Фиолетовые полосы отмечают кластеры сдвигов, больший ромб означает больший сдвиг, а в Summary видны время начала, балл и сместившиеся элементы. Insight Layout shift culprits показывает общий CLS и вероятные причины (web.dev).

Чтобы увидеть, какой элемент сдвигался у реальных посетителей, подключите сборку attribution из web-vitals: она сообщает цель, время и значение самого большого сдвига:

import {onCLS} from 'web-vitals/attribution';

onCLS(({value, rating, attribution}) => {
  console.log(rating, value, {
    target: attribution.largestShiftTarget,
    time: attribution.largestShiftTime,
    score: attribution.largestShiftValue,
  });
});

Сдвиги внутри iframe нельзя измерить веб-API, но они видны в Chrome UX Report, по данным web.dev. О том, как запускать Lighthouse и другие инструменты, читайте в руководстве по мобильному аудиту Lighthouse и руководстве по тесту скорости мобильной страницы.

Проверьте раскладку на ширине телефона

Раскладку, которая различается на десктопе и на телефоне, проще всего заметить на ширинах телефонов. Mobile View Extension перезагружает вкладку с user agent, размером экрана и pixel ratio телефона, так что вы видите мобильную версию страницы и можете смотреть, что смещается по ходу загрузки. CLS и другие метрики скорости расширение не измеряет и работает на вашем десктопном соединении, поэтому баннер или реклама, сдвигающие страницу на медленном телефоне, могут загрузиться слишком быстро, чтобы это заметить. Подтверждайте инструментами выше. Об остальных причинах, почему страница на телефоне выглядит иначе, читайте в статье почему сайт выглядит по-другому на телефоне.

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

Какой показатель CLS считается хорошим?

Хороший показатель CLS — 0,1 или меньше, а всё выше 0,25 — плохо; измеряется на 75-м процентиле загрузок страницы (web.dev, апрель 2023). Диапазон от 0,1 до 0,25 нужно улучшать.

Что вызывает сдвиг раскладки на мобильных?

Причины — изображения и видео без размеров, реклама, встраиваемые блоки и iframe без зарезервированного места, вставленные баннеры и уведомления о cookie, веб-шрифты, которые отображаются крупнее или мельче запасного, и анимации, меняющие свойства раскладки. Одно и то же смещение на телефоне получает больший балл, потому что доли считаются относительно меньшей области просмотра.

Как найти причину CLS?

Запишите трассировку на панели Performance в DevTools, откройте дорожку Layout shifts и посмотрите сместившиеся элементы в Summary. Для реальных посетителей используйте сборку attribution из web-vitals, чтобы получать largestShiftTarget.

Влияет ли CLS на SEO?

Google рекомендует добиваться хороших Core Web Vitals для успеха в поиске и пишет, что они согласуются с тем, что стремятся поощрять его основные системы ранжирования; прямым фактором ранжирования он их не называет (Google Search Central, обновлено в декабре 2025). Прямое влияние — на посетителей, которые теряют место, когда страница прыгает.

Откройте следующий сайт в мобильном виде.

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