Оптимизация Cumulative Layout Shift (CLS) сайта

Наша компания занимается разработкой, поддержкой и обслуживанием сайтов любой сложности. От простых одностраничных сайтов до масштабных кластерных систем построенных на микро сервисах. Опыт разработчиков подтвержден сертификатами от вендоров.
Разработка и обслуживание любых видов сайтов:
Информационные сайты или веб-приложения
Сайты визитки, landing page, корпоративные сайты, онлайн каталоги, квиз, промо-сайты, блоги, новостные ресурсы, информационные порталы, форумы, агрегаторы
Сайты или веб-приложения электронной коммерции
Интернет-магазины, B2B-порталы, маркетплейсы, онлайн-обменники, кэшбэк-сайты, биржи, дропшиппинг-платформы, парсеры товаров
Веб-приложения для управления бизнес-процессами
CRM-системы, ERP-системы, корпоративные порталы, системы управления производством, парсеры информации
Сайты или веб-приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, конструкторы сайтов, порталы предоставления электронных услуг, видеохостинги, тематические порталы

Это лишь некоторые из технических типов сайтов, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента

Предлагаемые услуги
Показано 1 из 1 услугВсе 2065 услуг
Оптимизация Cumulative Layout Shift (CLS) сайта
Средняя
от 1 рабочего дня до 3 рабочих дней
Часто задаваемые вопросы
Наши компетенции:
Этапы разработки
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1262
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1171
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    874
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1094
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    831
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Разработка веб-сайта для компании ФИКСПЕР
    851

Оптимизация CLS (Cumulative Layout Shift)

CLS — суммарная оценка смещений элементов страницы во время загрузки. Когда текст или кнопки прыгают в момент, когда пользователь на них кликает — это CLS. Цель: ≤ 0.1.

Формула расчёта

CLS = Σ (impact fraction × distance fraction) для каждого неожиданного смещения.

Impact fraction — доля viewport, которую занимали смещённые элементы. Distance fraction — расстояние смещения относительно viewport.

Диагностика

DevTools → Performance → запись → найти отметки «Layout Shift» (фиолетовые). Или:

new PerformanceObserver((list) => {
    for (const entry of list.getEntries()) {
        if (!entry.hadRecentInput) {
            console.log('Layout shift:', entry.value, entry.sources);
        }
    }
}).observe({ type: 'layout-shift', buffered: true });

entry.sources показывает конкретные DOM-элементы, которые сместились.

Изображения без размеров — самая частая причина

<!-- Плохо: браузер не знает размер до загрузки -->
<img src="product.webp" alt="...">

<!-- Хорошо: атрибуты width и height -->
<img src="product.webp" width="800" height="600" alt="...">

CSS для адаптивности с сохранением соотношения:

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

/* Или через aspect-ratio */
.product-image {
    aspect-ratio: 4 / 3;
    width: 100%;
    object-fit: cover;
}

Шрифты и FOUT

Font Swap вызывает смещение когда основной шрифт загружается и меняет системный (fallback).

/* Способ 1: font-display: optional — не показывать swap вообще */
@font-face {
    font-family: 'Inter';
    src: url('/fonts/inter.woff2') format('woff2');
    font-display: optional;
}

/* Способ 2: size-adjust — привести fallback к размеру основного шрифта */
@font-face {
    font-family: 'InterFallback';
    src: local('Arial');
    size-adjust: 107%;
    ascent-override: 90%;
    descent-override: 22%;
    line-gap-override: 0%;
}

body {
    font-family: 'Inter', 'InterFallback', sans-serif;
}

Инструмент для подбора size-adjust: fontaine пакет или next/font (автоматически подбирает size-adjust для Google Fonts).

Динамический контент

/* Баннер/рекламный блок: резервировать место до загрузки */
.ad-banner {
    min-height: 90px; /* стандартный leaderboard */
    background: #f5f5f5; /* placeholder */
}

/* Для адаптивных блоков */
.hero-section {
    aspect-ratio: 16 / 9;
    max-height: 600px;
}

Скелетоны вместо пустого места

Не оставлять место пустым — показывать skeleton placeholder с правильными размерами:

function ProductCardSkeleton() {
    return (
        <div className="product-card-skeleton">
            <div className="skeleton-image" style={{ aspectRatio: '1 / 1' }} />
            <div className="skeleton-title" style={{ height: '1.5rem', width: '80%' }} />
            <div className="skeleton-price" style={{ height: '1.25rem', width: '40%' }} />
        </div>
    );
}
.skeleton-image, .skeleton-title, .skeleton-price {
    background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
    background-size: 200% 100%;
    animation: shimmer 1.5s infinite;
    border-radius: 4px;
}

@keyframes shimmer {
    0% { background-position: 200% 0; }
    100% { background-position: -200% 0; }
}

Анимации

Анимации, изменяющие layout-свойства (width, height, top, left, margin, padding) вызывают CLS. Использовать только transform и opacity:

/* Плохо — вызывает layout reflow */
.modal { animation: slideDown 300ms; }
@keyframes slideDown { from { height: 0; } to { height: 400px; } }

/* Хорошо — только transform */
.modal { animation: slideDown 300ms; }
@keyframes slideDown {
    from { transform: translateY(-100%); opacity: 0; }
    to   { transform: translateY(0);    opacity: 1; }
}

contain: layout

Для изолированных компонентов — contain: layout или contain: strict предотвращает влияние внутренних изменений на внешний layout:

.widget-container {
    contain: layout;
}

Хедер с fixed-позиционированием

Sticky/fixed header при появлении не должен смещать контент. Паддинг на body:

body {
    padding-top: var(--header-height, 64px);
}
.header {
    position: fixed;
    top: 0;
    height: var(--header-height, 64px);
}

Срок оптимизации: 1–3 дня, основная работа — изображения и шрифты.