Страница прыгает при загрузке: как найти причину layout shift

Если страница прыгает при загрузке, пользователь успевает нажать не туда, текст сдвигается, кнопка уезжает вниз, а блоки появляются рывками. Это не только раздражает. Такие сдвиги часто показывают, что верстка не резервирует место под контент, который догружается позже.

Причину layout shift обычно можно найти без сложных инструментов: посмотреть, какие элементы появляются после первой отрисовки и меняют размер страницы.

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

Самая частая причина — картинки без width и height. Браузер не знает, сколько места оставить, сначала рисует страницу без изображения, потом картинка загружается и двигает контент.

<img src="/uploads/banner.jpg" alt="Баннер">

Лучше задать размеры:

<img src="/uploads/banner.jpg" width="1200" height="400" alt="Баннер">

Даже если CSS адаптирует изображение, атрибуты помогают браузеру заранее рассчитать пропорцию.

Lazy loading первого экрана

Lazy loading полезен для изображений ниже первого экрана. Но если лениво грузить главный баннер или первое фото товара, первый экран может появляться рывком.

<img src="/uploads/main.jpg" loading="lazy" width="1200" height="600" alt="">

Для ключевого изображения первого экрана lazy loading лучше не использовать. Оно должно загрузиться приоритетно.

Шрифты

Веб-шрифты могут менять размер текста после загрузки. Сначала браузер показывает системный шрифт, потом подключает фирменный, и строки переносятся иначе.

@font-face {
    font-family: 'SiteFont';
    src: url('/fonts/site.woff2') format('woff2');
    font-display: swap;
}

font-display помогает управлять поведением, но саму метрику шрифтов тоже нужно учитывать. Если запасной шрифт сильно отличается, прыжки будут заметнее.

Баннеры и виджеты

Чаты, cookie-плашки, рекламные блоки, формы обратной связи и внешние виджеты часто появляются после загрузки JS и двигают страницу. Лучше заранее резервировать место или показывать их поверх контента.

.promo-banner-placeholder {
    min-height: 120px;
}

Если блок может появиться, место под него должно быть предусмотрено.

Динамические блоки

Каталог может сначала показать пустую область, потом AJAX подгрузит фильтр, сортировку, цены или остатки. Если высота блока не задана, соседний контент сдвинется.

Для таких мест полезны skeleton-блоки или минимальная высота контейнера.

.catalog-filter {
    min-height: 240px;
}

Проверка в браузере

В Chrome DevTools можно включить отображение Layout Shift Regions. Также полезно записать загрузку во вкладке Performance и посмотреть, какие элементы двигались.

Но часто достаточно обычной проверки на медленной сети:

  1. Открыть DevTools.
  2. Включить Network throttling.
  3. Перезагрузить страницу.
  4. Посмотреть, какой блок появился и сдвинул контент.

Мобильная версия

На мобильных сдвиги заметнее: меньше экран, больше переносов текста, меню и баннеры занимают значительную часть страницы. Проверять нужно не только desktop.

Не лечить всё фиксированной высотой

Фиксированная высота может убрать прыжок, но создать обрезанный контент. Лучше резервировать разумное место и сохранять адаптивность.

.card-image {
    aspect-ratio: 1 / 1;
}

aspect-ratio часто удобнее, чем жёсткая высота.

Чек-лист

  1. Проверить изображения без width и height.
  2. Не ставить lazy loading на главный визуал первого экрана.
  3. Проверить web fonts и переносы текста.
  4. Зарезервировать место под баннеры и виджеты.
  5. Добавить min-height или skeleton для AJAX-блоков.
  6. Проверить страницу на медленной сети.
  7. Проверить мобильную версию отдельно.
  8. Использовать aspect-ratio для карточек и изображений.

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

Комментарии (0)

Пока нет комментариев. Будьте первым!