Веб-страницы с большим объемом контента, например с бесконечной прокруткой, сложными панелями управления или длинными статьями, могут медленно загружаться и реагировать на действия пользователя. Современные веб-технологии позволяют отложить отрисовку контента, который не виден сразу. Это значительно повышает производительность, не нарушая доступность и ожидания пользователей.
Чтобы оптимизировать отрисовку, вы можете использовать свойство CSS content-visibility и атрибут HTML hidden="until-found". Хотя оба инструмента помогают повысить эффективность, они предназначены для разных целей.
Когда использовать каждый из вариантов
| Сценарий/пример | Функция применена | Преимущество |
|---|---|---|
| 1. В нижней части страницы (отложенная начальная загрузка) | content-visibility: auto |
Браузер автоматически откладывает отрисовку макета, пока контейнер не окажется в видимой области экрана. Это позволяет сохранить стандартную скорость загрузки страницы. |
| 2. Переключить состояние (быстрое переключение между режимами просмотра) | content-visibility: hidden |
Пропускает расчеты макета для скрытых элементов div, но сохраняет состояние изоляции стиля, что позволяет мгновенно переключаться без структурных сдвигов (лучше, чем display: none). |
| 3. Searchable & Deferred (сворачиваемые сообщения) | hidden="until-found" |
Подробные инструкции о том, как совместить высокую производительность отрисовки с доступностью поиска по странице, вы найдете в статье Поиск скрытого контента. |
Как реализовать content-visibility: auto
Выбор контента за пределами экрана
ОБЯЗАТЕЛЬНО. Вы ДОЛЖНЫ тщательно определить, какие элементы получают content-visibility: auto.
- РЕКОМЕНДУЕТСЯ настраивать таргетинг на крупные автономные блоки макета, которые находятся строго ниже начального сгиба (например, карточки в бесконечной ленте, комментарии в конце страницы или разделы макета в нижней части страницы).
- НЕ применяйте это свойство к элементам в начальной области просмотра в верхней части страницы. Это заставляет браузер оценивать границы видимости перед отрисовкой, что, как ни парадоксально, задерживает загрузку страницы.
- РЕКОМЕНДУЕТСЯ выбирать элементы с глубокой или сложной внутренней структурой DOM, чтобы максимально снизить затраты на отрисовку.
Реализация
- ОБЯЗАТЕЛЬНО. Определите, какие тяжелые разделы не видны на экране при начальной загрузке.
- ОБЯЗАТЕЛЬНО. Примените
content-visibility: autoк каждому из этих элементов за пределами экрана. - ОБЯЗАТЕЛЬНО. Укажите приблизительный размер структуры макета, используя
contain-intrinsic-sizeдля каждого элемента.
Как пользоваться картой "contain-intrinsic-size"
ОБЯЗАТЕЛЬНО. Вы должны связать content-visibility: auto с contain-intrinsic-size. В противном случае браузер будет уменьшать высоту элемента до 0 пикселей, когда он находится за пределами экрана. Это приведет к значительному смещению макета и скачкам полосы прокрутки, когда пользователь прокручивает страницу.
Сокращенное свойство CSS contain-intrinsic-size используется в качестве заполнителя. Ключевое слово auto позволяет браузеру "запомнить" точный размер элемента после его отрисовки и использовать этот размер вместо плейсхолдера, если элемент снова окажется за пределами экрана.
Пример кода
/* DO ONLY apply this class to items OUTSIDE the initial layout viewport */
.heavy-section-deferred {
/* MANDATORY: Skips rendering calculations when off-screen */
content-visibility: auto;
/* Mandatory: Provide an estimated size to prevent layouts shifts.
- 'auto' is optional and enables the browser to remember the actual size
once rendered. It must be paired with a <length> value to be used for
the first render.
- 'none' tells the browser not to apply any intrinsic width to this element.
It can be used for either the height or the width value.
- '150px' is the estimated height of this element. This can be any valid
CSS <length> value.
*/
contain-intrinsic-size: auto none auto 150px;
}
Как реализовать content-visibility: hidden
- Определите тяжелые разделы. Найдите блоки макета, которые изначально скрыты (например, дополнительные строки в большой таблице данных).
- Примените CSS. Добавьте к элементу
content-visibility: hidden. - Показ элемента. Когда элемент должен появиться, измените свойство
content-visibilityнаvisibleилиauto.
Пример кода
.cached-view {
/* Hides content but caches rendering state */
content-visibility: hidden;
}
.cached-view.is-active {
content-visibility: visible;
}
Поскольку content-visibility: hidden исключает элемент и его дочерние элементы из дерева специальных возможностей и поиска по странице, НЕ используйте его, если контент должен оставаться доступным для обнаружения, пока он скрыт. Если вы хотите, чтобы скрытый контент можно было найти с помощью встроенной функции поиска по странице, используйте hidden="until-found", как описано в разделе Поиск скрытого контента.
Рекомендации
- ИСПОЛЬЗУЙТЕ
contain-intrinsic-sizeсcontent-visibility: auto. В противном случае при прокрутке высота будет пересчитываться, что приведет к скачкам макета области просмотра или визуальным сбоям. - НЕ применяйте
content-visibility: autoк элементам в области просмотра, которая видна без прокрутки, так как это задерживает отрисовку страницы. - ОБЯЗАТЕЛЬНАЯ проверка специальных возможностей. Применяя
content-visibility: auto, вы ДОЛЖНЫ проверить последовательную доступность клавиатуры. В некоторых конфигурациях технологий специальных возможностей узлы за пределами экрана, использующиеcontent-visibility: auto, могут быть исключены из дерева специальных возможностей или последовательных маршрутов навигации, пока фокус не будет принудительно перемещен внутрь них. Протестируйте линейную навигацию за пределами экрана, используя только клавиатуру.
Резервные стратегии
content-visibility резервное объявление
Если content-visibility не поддерживается, браузер проигнорирует его. В большинстве случаев резервное объявление для content-visibility: auto не требуется, но без него эффективность будет ниже. В неподдерживаемом браузере элементы content-visibility: hidden будут полностью видны. Используйте обнаружение функций, чтобы реализовать резервный вариант.
/* Default for everyone */
.inactive {
display: none;
}
/* Modern Browsers only */
@supports (content-visibility: hidden) {
.inactive {
display: block; /* Turn the layout box back on */
content-visibility: hidden;
}
}