Как на JS реализовать «скелетную загрузку» (Skeleton Screen), чтобы визуально скрасить время ожидания ответа от сервера?
Skeleton Screen (скелетная загрузка) — это техника UX, при которой вместо спиннера или пустого экрана пользователь видит «серые заглушки», имитирующие форму будущего контента. Это снижает субъективное ощущение ожидания и делает интерфейс более отзывчивым.
## Базовая реализация на чистом JS и CSS
### 1. HTML-структура скелетона
Создайте блоки-заглушки, повторяющие структуру реального контента:
html
### 2. CSS-анимация «пульсации»
Классический эффект достигается через анимацию градиента:
css
.skeleton {
background: #e0e0e0;
border-radius: 4px;
overflow: hidden;
position: relative;
}
.skeleton::after {
content: »;
position: absolute;
top: 0; left: -100%;
width: 100%; height: 100%;
background: linear-gradient(90deg, transparent, rgba(255,255,255,0.4), transparent);
animation: shimmer 1.5s infinite;
}
@keyframes shimmer {
100% { left: 100%; }
}
.skeleton-avatar { width: 48px; height: 48px; border-radius: 50%; background: #ccc; }
.skeleton-line { height: 14px; margin: 8px 0; background: #ccc; border-radius: 4px; }
.skeleton-line.short { width: 60%; }
### 3. JavaScript: показ скелетона и замена реальными данными
javascript
async function loadContent() {
const container = document.getElementById(‘content’);
// Показываем скелетон
container.innerHTML = renderSkeleton(3);
try {
const response = await fetch(‘/api/items’);
const data = await response.json();
// Небольшая задержка для плавности (опционально)
await new Promise(r => setTimeout(r, 300));
// Заменяем скелетон реальным контентом
container.innerHTML = data.map(item => `
${item.name}
${item.role}
`).join(»);
} catch (error) {
container.innerHTML = ‘
Ошибка загрузки данных
‘;
}
}
function renderSkeleton(count) {
return Array.from({ length: count }, () => `
`).join(»);
}
loadContent();
## Реализация через CSS-классы (toggle-подход)
Альтернативно можно хранить один DOM и переключать классы:
javascript
function showSkeleton(el) { el.classList.add(‘is-loading’); }
function hideSkeleton(el) { el.classList.remove(‘is-loading’); }
## Советы по реализации
— **Точно имитируйте структуру** — скелетон должен совпадать по размерам с реальным контентом, иначе будет сильный «прыжок» при замене.
— **Не злоупотребляйте** — для запросов быстрее 300 мс скелетон может мелькнуть и раздражить пользователя. Используйте задержку показа.
— **Доступность** — добавьте `aria-busy=»true»` на контейнер во время загрузки.
— **React/Vue** — в современных фреймворках удобно использовать условный рендеринг: `{isLoading ? : }`.
Скелетная загрузка — простой и эффективный способ улучшить воспринимаемую производительность без изменения реальной скорости.
