Я Максим, веб-разработчик. Знаете эти серые прямоугольники, которые мигают, пока контент загружается? Это skeleton screens — скелетоны загрузки. Они не ускоряют реальную загрузку страницы ни на миллисекунду, но кардинально ускоряют воспринимаемую. И разница в ощущениях пользователя — огромная. Расскажу, как скелетоны работают, где их применять, как реализовать и какие ошибки я встречаю чаще всего.
Почему воспринимаемая скорость важнее реальной
Есть хорошо известный факт из UX-исследований: пользователь оценивает скорость сайта не по секундомеру, а по ощущениям. Две страницы, которые загружаются за одинаковые 1.5 секунды, воспринимаются совершенно по-разному в зависимости от того, что происходит на экране в момент ожидания. Пустой белый экран — раздражает. Спиннер — терпимо, но тревожно. Скелетон, который показывает структуру будущего контента, — комфортно, потому что мозг уже начинает «читать» страницу.
Исследования Google и Facebook показали, что skeleton screens сокращают субъективное время ожидания на 20–30% по сравнению со спиннерами. Для бизнес-сайта это прямо влияет на конверсию: каждая секунда задержки увеличивает показатель отказов. Скелетоны не убирают задержку, но убирают ощущение задержки — а для пользователя это одно и то же.
Спиннер vs скелетон: в чём принципиальная разница
Классический подход при асинхронной загрузке данных — показать спиннер (крутящийся индикатор) и ждать. Проблема спиннера в том, что он говорит «жди», но не говорит «что будет дальше». Пользователь видит вращающийся кружок и не понимает: это загрузка данных на 200 миллисекунд или зависание на 10 секунд? Стоит ли ждать или лучше закрыть вкладку?
Скелетон работает иначе. Он показывает структуру будущего контента: вот здесь будет заголовок, тут — абзац текста, там — изображение. Мозг начинает «предвкушать» контент, строить ожидания, и когда реальные данные появляются — они заполняют уже знакомый каркас. Это работает по тому же принципу, что и прогресс-бар: любая визуальная обратная связь о прогрессе делает ожидание более терпимым.
Ещё одно преимущество скелетона — стабильность layout. Если контент загружается без скелетона, элементы страницы «прыгают» по мере появления данных: сначала заголовок, потом текст сдвигается, потом изображение встраивается и всё снова сдвигается. Это CLS (Cumulative Layout Shift) — одна из метрик Core Web Vitals. Скелетон резервирует место для каждого элемента заранее, и при загрузке данных layout остаётся стабильным. Это плюс и для UX, и для SEO.
Где использовать skeleton screens
Карточки товаров в каталоге
Пока данные грузятся из API — серые прямоугольники на месте фото, названия, цены и кнопки «В корзину». Потом они плавно заменяются реальным контентом. Этот паттерн стал стандартом для интернет-магазинов: Wildberries, Ozon, Amazon — все используют скелетоны при подгрузке каталога.
Лента публикаций и новостей
Блог, лента соцсетей, новостной раздел — скелетон идеален для контента, который подгружается динамически. При бесконечном скролле (infinite scroll) скелетоны внизу страницы показывают, что новый контент загружается, и создают ощущение непрерывного потока.
Личный кабинет и дашборды
Дашборды с данными из нескольких источников — классический кейс. Каждый блок (статистика, графики, последние заказы, уведомления) загружается по мере готовности. Скелетон для каждого блока позволяет показать общую структуру дашборда мгновенно, а данные подтягивать по мере готовности. Это значительно лучше, чем ждать, пока все API ответят, и только потом показывать страницу целиком.
Профили пользователей и страницы с данными
Любая страница, где основной контент зависит от ответа сервера: профиль пользователя, детальная страница товара, результаты поиска, история заказов.
Где скелетоны НЕ нужны
Не используйте скелетоны для статичных страниц. Если страница рендерится сервером (SSR или SSG) и контент доступен при первой загрузке — скелетон бессмысленный. Он для случаев, когда данные приходят асинхронно после загрузки страницы. Также не нужны скелетоны для элементов, которые загружаются мгновенно (менее 100 мс) — мелькнувший скелетон выглядит как баг, а не как UX-улучшение.
Техническая реализация
CSS-скелетон — самый простой вариант
Серый блок с анимацией shimmer (бегущий блик). Три ключевых свойства: background цвета #e0e0e0, border-radius для скругления углов (чтобы скелетон повторял форму будущего элемента), и animation с linear-gradient для создания эффекта бегущего блика. Анимация shimmer обычно длится 1.5–2 секунды и повторяется бесконечно.
Важный момент: цвет скелетона должен соответствовать цветовой схеме сайта. На светлой теме — светло-серый (#e0e0e0 — #f0f0f0). На тёмной теме — тёмно-серый (#2a2a2a — #3a3a3a). Если на сайте поддерживается dark mode — скелетоны тоже должны адаптироваться.
React: react-loading-skeleton
В React-проектах я чаще всего использую библиотеку react-loading-skeleton — минимум кода, поддержка кастомных размеров и количества строк, автоматическая анимация. Подключаете компонент Skeleton, указываете width, height и count — готово. Библиотека весит несколько килобайт и не тянет за собой тяжёлых зависимостей.
Для более сложных случаев — например, когда скелетон должен точно повторять layout карточки товара — я создаю отдельный компонент-скелетон, который использует ту же сетку CSS, что и реальная карточка, но вместо данных — серые блоки.
Vue: vue-content-loader
Для Vue-проектов — vue-content-loader. Позволяет создавать SVG-скелетоны произвольной формы: не только прямоугольники, но и круги (для аватаров), скруглённые блоки, комбинации разных форм.
Чистый JavaScript и HTML
Для проектов без фреймворков — CSS-классы (.skeleton, .skeleton-text, .skeleton-image), которые добавляются к элементам до загрузки данных и заменяются на реальный контент после. Подход простой: рендерите HTML с классами-скелетонами, делаете fetch-запрос, по получении данных заменяете innerHTML элементов и убираете классы скелетонов.
Правила хорошего скелетона
Отражайте реальную структуру контента. Скелетон должен максимально повторять layout будущего элемента. Если карточка товара — это фото сверху и текст снизу, скелетон — прямоугольник сверху и три линии разной длины снизу. Чем точнее скелетон повторяет финальный вид, тем плавнее воспринимается загрузка.
Не показывайте скелетон дольше 3 секунд. Если данные грузятся дольше — у вас проблема с бэкендом или сетью, а не с UX. Скелетон маскирует задержку в 200–2000 мс. Если задержка больше — пользователь начинает сомневаться, что контент вообще загрузится, и скелетон перестаёт помогать. Для долгих загрузок лучше комбинировать скелетон с текстовым индикатором: «Загружаем данные…».
Плавная замена скелетона на контент. Контент должен появляться вместо скелетона без рывков и дёрганий. Fade-in анимация на 150–300 мс — достаточно. Мгновенная замена (без анимации) тоже допустима, если размеры скелетона точно совпадают с размерами контента.
Избегайте «мерцания» скелетона. Если данные загружаются очень быстро (менее 200 мс), скелетон мелькнёт и исчезнет — это выглядит как визуальный глитч. Добавьте минимальное время отображения: если данные пришли быстрее 200 мс — покажите скелетон хотя бы 200 мс перед заменой. Это звучит парадоксально (искусственно замедляем отображение), но визуально смотрится значительно лучше.
Не переусердствуйте с детализацией. Скелетон — это намёк на структуру, а не точная копия. Достаточно показать основные блоки: изображение, заголовок, несколько строк текста. Не нужно имитировать каждую иконку, каждый разделитель и каждый пиксель будущего элемента.
Скелетоны и Core Web Vitals
Грамотные скелетоны положительно влияют на метрику CLS (Cumulative Layout Shift), потому что резервируют место для асинхронного контента. Без скелетонов динамически загружаемые элементы сдвигают layout при появлении — это штрафуется поисковиками. Со скелетонами layout стабилен с первого рендера. Для Яндекса это тоже значимый фактор — поведенческие сигналы пользователей на стабильном layout лучше, чем на дёргающейся странице.
Скелетоны — мелкая деталь, которая делает сайт заметно профессиональнее. Если ваш сайт загружает данные асинхронно — добавьте скелетоны вместо спиннеров. Реализация занимает несколько часов, а результат заметен сразу: и пользователям, и в метриках.