content-visibility — lazy rendering
content-visibility: auto— CSS-свойство, указывающее браузеру пропустить layout и rendering элементов, находящихся за пределами видимой области (viewport), и отрендерить их только при появлении на экране. Один из самых эффективных CSS-приёмов для ускорения начальной загрузки.
Зачем нужно
Браузер обычно рендерит весь документ при загрузке, даже элементы, которые пользователь никогда не увидит (длинные страницы, бесконечный скролл). content-visibility: auto сокращает начальное время рендеринга на 40-60% для длинных страниц, особенно с большим количеством DOM-элементов.
Где используется
- Длинные страницы с большим количеством секций (лендинги, документация)
- Бесконечные списки без виртуализации
- Страницы блогов и новостей с множеством карточек
- Профили пользователей с историей активности
Основной контент
Базовое использование
/* Пропустить rendering элементов за пределами viewport */
.article-section {
content-visibility: auto;
/* ОБЯЗАТЕЛЬНО: указать предполагаемый размер,
иначе scrollbar будет "прыгать" при скролле */
contain-intrinsic-size: 0 500px; /* width: auto, height: 500px */
}
Полный пример с длинной страницей
<style>
.section {
content-visibility: auto;
contain-intrinsic-size: 0 600px; /* Примерная высота секции */
}
</style>
<!-- Только первые видимые секции рендерятся сразу -->
<main>
<section class="section" id="hero">...</section>
<section class="section" id="features">...</section>
<section class="section" id="pricing">...</section>
<!-- Эти секции рендерятся при скролле к ним: -->
<section class="section" id="testimonials">...</section>
<section class="section" id="faq">...</section>
<section class="section" id="footer">...</section>
</main>
contain-intrinsic-size — точный или приблизительный
.card-list-item {
content-visibility: auto;
/* Фиксированный размер (точный, но негибкий) */
contain-intrinsic-size: 300px 200px;
/* auto: запоминает реальный размер после первого рендера */
contain-intrinsic-size: auto 200px;
/* auto height сохраняется в кеш браузера → плавный скролл */
}
Сравнение: content-visibility vs lazy loading
/* content-visibility — CSS, для секций страницы */
.page-section {
content-visibility: auto;
contain-intrinsic-size: 0 400px;
/* Ноль JavaScript, работает сразу */
}
/* Lazy loading — для изображений */
img {
loading: lazy;
/* Стандарт HTML, поддерживается всеми браузерами */
}
/* IntersectionObserver — для JavaScript компонентов */
/* content-visibility эффективнее для чистого CSS-контента */
Измерение эффекта (Performance API)
// Сравнение времени рендеринга до и после
const observer = new PerformanceObserver(list => {
for (const entry of list.getEntries) {
if (entry.name === 'first-contentful-paint') {
console.log(`FCP: ${entry.startTime}ms`);
}
}
});
observer.observe({ entryTypes: ['paint', 'largest-contentful-paint'] });
// Ожидаемый результат на длинных страницах:
// Без content-visibility: FCP = 800ms, LCP = 2800ms
// С content-visibility: FCP = 500ms, LCP = 1900ms
Частые ошибки
- Отсутствие
contain-intrinsic-size— скроллбар "прыгает" при прокрутке - Применение к элементам в viewport — бессмысленно, добавляет overhead
- Использование для элементов с JavaScript-зависимым размером — layout пересчитывается при скролле
- Применение к элементам с CSS-анимациями — могут не запускаться до появления в viewport
Связанные темы
- _MOC Производительность
- contain -- CSS Containment
- Виртуализация длинных списков
- Как браузер рендерит страницу