CLS: что такое Cumulative Layout Shift
Страница может загружаться быстро и при этом восприниматься как сломанная. Вы начинаете читать, появляется изображение, текст внезапно сдвигается вниз, а кнопка, на которую вы собирались нажать, оказывается в другом месте. Именно такую нестабильность и измеряет Cumulative Layout Shift (CLS).
CLS — один из трёх показателей Core Web Vitals наряду с Largest Contentful Paint (LCP) и Interaction to Next Paint (INP). В отличие от них, CLS измеряется не в миллисекундах. Он представляет собой безразмерную оценку, которая показывает, насколько сильно видимый контент неожиданно смещался и насколько значительными были эти перемещения. (web.dev)
Что такое CLS?
Cumulative Layout Shift измеряет визуальную стабильность веб-страницы, оценивая неожиданные перемещения видимого контента.
Layout shift происходит, когда видимый элемент меняет своё исходное положение между двумя отрисованными кадрами. CLS объединяет неожиданные смещения в короткие группы, называемые session windows, и использует окно с наибольшей суммарной оценкой сдвигов. (web.dev)
Простой пример — статья, в которой браузер сначала показывает заголовок и текст, а затем над ними загружается изображение, для которого заранее не было зарезервировано место. Изображение занимает пространство, сдвигает статью вниз и заставляет читателя снова искать место, на котором он остановился.
Такое перемещение влияет на CLS.
Оценка CLS
Текущие пороговые значения Google:
| CLS | Оценка |
|---|---|
| 0.10 или ниже | Хорошо |
| Выше 0.10 до 0.25 | Требует улучшения |
| Выше 0.25 | Плохо |
Для оценки Core Web Vitals Google рекомендует ориентироваться на 75-й процентиль посещений страницы, отдельно для мобильных и десктопных устройств. На практике это означает, что как минимум 75% посещений должны иметь CLS не выше 0.10.
CLS — безразмерная величина. Значение 0.1 не означает 0.1 секунды. Оно отражает совокупную серьёзность неожиданных визуальных смещений.
Почему CLS важен
Нестабильность layout напрямую влияет на удобство использования.
Из-за смещения пользователь может потерять место, где он читал, элемент формы может переместиться во время взаимодействия, а человек может случайно нажать не на ту кнопку, которую собирался выбрать. Особенно заметной проблема становится в медленных сетях, где изображения, реклама, шрифты, ответы API и сторонний контент могут появляться позже, чем при локальной разработке. (web.dev)
CLS также имеет значение для поисковой эффективности. Google указывает Core Web Vitals среди сигналов, используемых его системами ранжирования, и рекомендует достигать хороших показателей Core Web Vitals для Search и пользовательского опыта. Однако хороший CLS не гарантирует более высоких позиций. Google учитывает множество сигналов, а Core Web Vitals — лишь одна из составляющих page experience. (developers.google.com)
INTERNAL LINK: Core Web Vitals Explained
Как работает CLS
CLS начинается с оценки отдельных layout shifts.
Для каждого учитываемого смещения браузер оценивает два фактора:
layout shift score = impact fraction × distance fraction
Impact fraction показывает, какая доля viewport была затронута нестабильными элементами до и после перемещения.
Distance fraction показывает, насколько далеко переместился наиболее сильно сдвинутый нестабильный элемент относительно наибольшего измерения viewport. (web.dev)
Допустим, перемещающийся элемент затрагивает 75% viewport и смещается на расстояние, равное 25% его наибольшего измерения:
0.75 × 0.25 = 0.1875
Оценка layout shift для этого события будет равна 0.1875.
Session Windows
Современный CLS не просто складывает все layout shifts, которые произошли за всё время существования страницы.
Отдельные неожиданные смещения объединяются в session windows. Одно session window включает сдвиги, между которыми прошло менее одной секунды, и может длиться максимум пять секунд.
CLS страницы равен суммарной оценке самого большого session window. (web.dev)
Такой подход не позволяет автоматически ухудшать оценку долгоживущих страниц, например single-page applications и интерфейсов с infinite scroll, только потому, что пользователь держит их открытыми дольше.
Ожидаемые смещения
Не каждое движение влияет на CLS.
Смещение, напрямую вызванное дискретным пользовательским действием — например, кликом, касанием или нажатием клавиши, — может не учитываться, если оно произошло в течение 500 миллисекунд после этого действия. Layout Instability API предоставляет эту информацию через свойство hadRecentInput. (web.dev)
Например, раскрытие accordion сразу после клика пользователя обычно считается ожидаемым поведением.
Но со scrolling ситуация отличается. Непрерывные взаимодействия, такие как scrolling, не обрабатываются таким же образом. Если lazy-loaded контент внезапно сдвигает существующий контент вниз во время прокрутки, такое перемещение всё ещё может влиять на CLS.
Основные причины CLS
Самые распространённые причины довольно просты.
Изображения без заданных размеров
Изображение без заранее известных размеров изначально может занимать мало места или вообще не занимать его. Когда изображение загружается, браузер определяет его размер и сдвигает окружающий контент.
Зарезервируйте необходимое пространство с помощью HTML-размеров:
<img
src="product.jpg"
width="1200"
height="800"
alt="Product"
>
Responsive CSS всё равно может изменять размер изображения:
img {
width: 100%;
height: auto;
}
Современные браузеры могут использовать атрибуты width и height, чтобы определить aspect ratio изображения ещё до завершения его загрузки. (web.dev)
Реклама и embeds
Реклама, видео-embeds, карты, социальные виджеты и iframes часто загружаются уже после окружающего контента.
Если изначально у их контейнера нет высоты, всё, что расположено ниже, может сместиться после появления содержимого.
Заранее зарезервируйте предсказуемое пространство:
.video-wrapper {
aspect-ratio: 16 / 9;
}
Для контента с переменной высотой подходящий min-height или placeholder может уменьшить смещения. При этом удаление зарезервированного пространства, если реклама не появилась, само по себе может вызвать новый layout shift, поэтому placeholders нужно проектировать аккуратно. (web.dev)
Динамический контент
Cookie-уведомления, рекламные баннеры, alerts, рекомендации и асинхронно загружаемые компоненты могут вызывать крупные смещения, если вставляются выше контента, который пользователь уже просматривает.
Лучше заранее резервировать для них место или, когда это уместно, показывать компонент как overlay вместо его вставки в document flow.
Web Fonts
Fallback-шрифт и итоговый web font могут отличаться шириной символов, высотой строки и другими метриками. Когда основной шрифт загружается, строки могут переноситься иначе и сдвигать окружающий контент.
Среди возможных улучшений — выбор более похожего fallback-шрифта, более ранняя загрузка критически важных шрифтов, правильное использование font-display, а также настройка метрик fallback-шрифта через свойства вроде size-adjust, ascent-override, descent-override и line-gap-override. (web.dev)
Анимации, влияющие на layout
Анимация свойств вроде top, left, width или height может изменять layout.
По возможности используйте transforms, которые лучше обрабатываются compositor:
.card {
transform: translateY(20px);
}
вместо постоянного изменения:
.card {
top: 20px;
}
Использование transform: translate() или transform: scale() позволяет визуально перемещать элементы без такого же типа layout shift. (web.dev)
Как измерять CLS
Начинайте с field data.
Chrome UX Report (CrUX) содержит агрегированные реальные пользовательские данные Core Web Vitals, включая CLS. PageSpeed Insights может показывать field data из CrUX, если доступен достаточный объём данных, а Search Console группирует страницы в отчёте Core Web Vitals. CrUX показывает CLS на уровне 75-го процентиля и рассматривает его как безразмерную метрику. (developer.chrome.com)
Затем используйте lab tools, чтобы найти источник проблемы.
Performance panel в Chrome DevTools показывает отдельные layout shifts и объединяет их в clusters. Можно изучить оценки сдвигов, затронутые элементы, время, screenshots и потенциальные причины. Инструменты Rendering в Chrome также могут визуально подсвечивать области layout shift. (developer.chrome.com)
Полезный workflow выглядит так:
Плохой field CLS → воспроизвести страницу → найти крупнейший shift cluster → изучить сдвинутые элементы → определить элемент, который вызвал перемещение → исправить → измерить снова.
Не стоит автоматически считать переместившийся элемент причиной проблемы. Например, абзац может сдвинуться из-за рекламы, изображения, баннера или другого компонента выше него, который изменил свой размер. (web.dev)
Lab CLS и Field CLS
Одна из распространённых ошибок при диагностике — ожидать, что CLS в Lighthouse и у реальных пользователей будет полностью совпадать.
Они измеряют разные ситуации.
Обычный тест Lighthouse в основном наблюдает за первоначальной загрузкой страницы. Реальные пользователи могут продолжать прокручивать страницу, открывать меню, загружать дополнительные товары, запускать route changes или держать страницу открытой несколько минут. Поэтому неожиданные смещения, происходящие позже, могут появляться в CrUX, даже если обычный тест загрузки в Lighthouse показывает стабильный результат. (web.dev)
Если lab CLS низкий, а field CLS высокий, исследуйте взаимодействия и scrolling после загрузки страницы.
INTERNAL LINK: Lab Data vs Field Data
Диагностика CLS
Для более сложных случаев Chromium предоставляет информацию о layout shifts через Layout Instability API:
new PerformanceObserver((entryList) => {
for (const entry of entryList.getEntries()) {
if (!entry.hadRecentInput) {
console.log('Layout shift:', entry.value, entry.sources);
}
}
}).observe({
type: 'layout-shift',
buffered: true
});
Это полезно для диагностики отдельных смещений, но такой код не является полной реализацией метрики CLS. Для корректного расчёта CLS необходимо объединять смещения в session windows и учитывать дополнительные lifecycle-сценарии. Для production Real User Monitoring обычно безопаснее использовать библиотеку web-vitals, чем реализовывать всю метрику самостоятельно. (web.dev)
Распространённые заблуждения
«CLS измеряет скорость загрузки». Нет. CLS измеряет визуальную стабильность. Страница может загружаться быстро и при этом иметь очень плохой CLS.
«Любое движение увеличивает CLS». Нет. CLS учитывает неожиданные layout shifts. Некоторые смещения, тесно связанные с дискретным пользовательским вводом, исключаются.
«CLS 0 в Lighthouse означает, что пользователи тоже видят CLS 0». Не обязательно. Post-load shifts могут присутствовать в field data, но вообще не возникнуть во время простого синтетического теста загрузки страницы.
«Если элемент сдвинулся, значит именно он вызвал проблему». Не всегда. Его мог просто вытеснить другой элемент.
Рекомендация SeoNest
Рассматривайте CLS как проблему архитектуры layout, а не как показатель, который нужно оптимизировать уже после завершения разработки.
Заранее резервируйте пространство для медиа и сторонних компонентов. Проектируйте асинхронный UI так, чтобы загрузка контента не вызывала неожиданных смещений уже отображаемых элементов. Тестируйте страницы в реалистичных сетевых условиях и пользовательских сценариях, а не только во время первоначальной загрузки.
Для production-сайтов сочетайте field monitoring с диагностикой через DevTools. Field data показывает, сталкиваются ли реальные пользователи с нестабильностью; диагностические инструменты помогают понять, почему это происходит.
FAQ
CLS входит в Core Web Vitals?
Да. CLS — показатель Core Web Vitals, измеряющий визуальную стабильность. Другие текущие Core Web Vitals — LCP для loading performance и INP для responsiveness. (developers.google.com)
Какой CLS считается хорошим?
CLS 0.10 или ниже на 75-м процентиле посещений страницы считается хорошим показателем. (web.dev)
CLS измеряется в секундах?
Нет. CLS — безразмерная оценка.
Может ли lazy loading ухудшить CLS?
Сам по себе lazy loading не обязательно является проблемой. CLS возникает, когда lazy-loaded контент появляется без заранее зарезервированного для него пространства.
Может ли CLS возникать после загрузки страницы?
Да. Неожиданные смещения могут возникать во время scrolling, динамических обновлений контента, SPA transitions и других действий после загрузки. Это одна из причин, по которой field CLS может быть выше, чем CLS в Lighthouse. (web.dev)
Итог
CLS отвечает на простой вопрос: остаётся ли страница там, где пользователь ожидает её увидеть?
Хороший CLS не требует полностью статичной страницы. Современные интерфейсы по-прежнему могут динамически загружать контент, анимировать элементы и реагировать на действия пользователя. Главное — предсказуемость: резервируйте место до появления контента, не сдвигайте существующие элементы неожиданно и проверяйте результат на данных реальных пользователей.
Если layout стабилен по своей архитектуре, хороший CLS обычно становится естественным результатом.
Sources
- web.dev — Cumulative Layout Shift (CLS). Last updated April 12, 2023. Cumulative Layout Shift (CLS) (web.dev)
- web.dev — Optimize Cumulative Layout Shift. Published May 5, 2020; updated February 7, 2025. Optimize Cumulative Layout Shift (web.dev)
- web.dev — Debug layout shifts. Published March 11, 2021; updated February 7, 2025. Debug layout shifts (web.dev)
- Google Search Central — Understanding Core Web Vitals and Google search results. Last updated December 10, 2025. Google Search Central Core Web Vitals documentation (developers.google.com)
- Chrome for Developers — Chrome UX Report: Metrics. Published June 23, 2022; updated September 15, 2026. Chrome UX Report Metrics (developer.chrome.com)
- Chrome for Developers — Performance features reference. Chrome DevTools Performance reference (developer.chrome.com)


