Функция onCLS и её поведение

onCLS — это одна из ключевых функций библиотеки Web Vitals в JavaScript, предназначенная для измерения Cumulative Layout Shift (CLS), то есть совокупного смещения макета. CLS отражает визуальную стабильность страницы: каждый раз, когда элементы на странице неожиданно смещаются, пользователю создается ощущение «подпрыгивания» контента.


Принцип работы CLS

CLS измеряет все смещения видимых элементов страницы в течение жизненного цикла страницы и суммирует их. Каждое смещение вычисляется как произведение доли видимой области, затронутой смещением, на долю перемещения элементов. Формула:

Impact Fraction × Distance Fraction = Layout Shift Score
  • Impact Fraction — доля экрана, которую занимает смещённый элемент.
  • Distance Fraction — отношение расстояния смещения элемента к размеру экрана.

CLS — это сумма всех Layout Shift Score за период, пока пользователь взаимодействует с страницей.


Поведение функции onCLS

Функция onCLS используется для отслеживания CLS в реальном времени. Её сигнатура выглядит так:

import { onCLS } from 'web-vitals';

onCLS(callback: (metric: Metric) => void, reportAllChanges?: boolean);
  • callback — функция, которая получает объект Metric с данными о текущем значении CLS.
  • reportAllChanges — необязательный параметр. Если установлен в true, callback вызывается при каждом изменении CLS, а не только при окончательном значении.

Пример использования:

onCLS(metric => {
  console.log('CLS value:', metric.value);
  console.log('CLS entries:', metric.entries);
});

Структура объекта Metric

Объект, который передается в callback, имеет следующую структуру:

interface Metric {
  name: 'CLS';
  value: number;
  delta: number;
  id: string;
  entries: LayoutShift[];
}
  • name — всегда 'CLS'.
  • value — текущее накопленное значение CLS.
  • delta — изменение CLS с момента последнего вызова callback.
  • id — уникальный идентификатор метрики.
  • entries — массив объектов LayoutShift, содержащих детали каждого смещения.

Каждый объект LayoutShift содержит:

interface LayoutShift {
  value: number;            // Score для одного смещения
  sources: ShiftSource[];   // Элементы, вызвавшие смещение
  hadRecentInput: boolean;  // Был ли пользовательский ввод перед смещением
}

Особенности поведения на разных этапах загрузки

  1. Initial Load (загрузка страницы) CLS измеряет смещения, которые происходят до взаимодействия пользователя. Смещения, вызванные асинхронной подгрузкой изображений или рекламных блоков, добавляются к общему значению.

  2. Interactive Stage (интерактивное взаимодействие) По умолчанию CLS игнорирует смещения, вызванные пользовательским вводом (например, прокрутка, клики), чтобы исключить «естественные» смещения.

  3. Долгие страницы Для страниц с большим количеством динамического контента рекомендуется включать параметр reportAllChanges, чтобы отслеживать CLS в реальном времени и анализировать пиковые смещения.


Рекомендации по использованию

  • Включать onCLS на всех страницах с динамическим контентом (лендинги, новостные сайты).
  • Анализировать entries для выявления конкретных элементов, вызывающих смещения.
  • Обновлять значение CLS при каждом изменении, если требуется детальный мониторинг пользовательского опыта.
  • Игнорировать смещения, вызванные взаимодействием пользователя, чтобы метрика отражала именно проблемы стабильности макета.

Интеграция с аналитикой

Для отправки CLS в систему аналитики достаточно вызвать callback и передать значение:

onCLS(metric => {
  fetch('/analytics', {
    method: 'POST',
    body: JSON.stringify({
      metricName: metric.name,
      value: metric.value,
      entries: metric.entries.length
    })
  });
});

Такой подход позволяет не только фиксировать общую метрику, но и анализировать причины смещений для оптимизации страницы.


Важные нюансы

  • CLS — это накопительная метрика, а не моментальная. Пиковые смещения суммируются, что делает её чувствительной к любым динамическим изменениям.
  • Смещения, вызванные пользовательским вводом, не учитываются, поэтому наблюдаемые значения могут быть ниже «реального визуального ощущения» пользователя, если страница активно реагирует на действия.
  • Использование reportAllChanges = true помогает отслеживать промежуточные значения для более точного анализа, особенно при длительных сессиях пользователя.