Уменьшите время начальной загрузки, пропустив рендеринг закадрового контента.
Опубликовано: 5 августа 2020 г.
Свойство content-visibility
позволяет пользовательскому агенту пропускать работу по рендерингу элемента, включая макет и рисование, до тех пор, пока он не понадобится. Поскольку рендеринг пропускается, если большая часть вашего контента находится за кадром, использование свойства content-visibility
значительно ускоряет начальную загрузку пользователя. Это также позволяет быстрее взаимодействовать с контентом на экране. Довольно аккуратно.
CSS-сдерживание
Ключевая и основная цель сдерживания CSS — обеспечить повышение производительности рендеринга веб-контента за счет предсказуемой изоляции поддерева DOM от остальной части страницы.
По сути, разработчик может сообщить браузеру, какие части страницы инкапсулированы как набор контента, что позволяет браузерам анализировать контент без необходимости учитывать состояние за пределами поддерева. Зная, какие части контента (поддеревья) содержат изолированный контент, браузер может принимать решения по оптимизации рендеринга страниц.
Существует четыре типа CSS-содержания , каждый из которых представляет собой потенциальное значение свойства CSS- contain
, которое можно объединить в список значений, разделенных пробелами:
-
size
: ограничение размера элемента гарантирует, что блок элемента можно будет разместить без необходимости проверки его потомков. Это означает, что мы потенциально можем пропустить размещение потомков, если все, что нам нужно, это размер элемента. -
layout
: сдерживание макета означает, что потомки не влияют на внешний макет других блоков на странице. Это позволяет нам потенциально пропустить размещение потомков, если все, что мы хотим сделать, это расположить другие блоки. -
style
: Включение стиля гарантирует, что свойства, которые могут влиять не только на его потомков, не выходят за пределы элемента (например, счетчики). Это позволяет нам потенциально пропустить вычисление стилей для потомков, если все, что нам нужно, — это вычислить стили для других элементов. -
paint
: сдерживание краски гарантирует, что потомки содержащего блока не будут отображаться за его пределами. Ничто не может явно переполнять элемент, и если элемент находится за пределами экрана или по какой-либо причине не виден, его потомки также не будут видны. Это позволяет нам потенциально пропустить рисование потомков, если элемент находится за кадром.
Пропустить работу по рендерингу с помощью content-visibility
Может быть сложно определить, какие значения ограничения использовать, поскольку оптимизация браузера может начаться только тогда, когда указан соответствующий набор. Вы можете поиграть со значениями, чтобы увидеть , что работает лучше всего , или вы можете использовать content-visibility
для автоматического применения необходимого сдерживания. content-visibility
гарантирует, что вы получите максимальный прирост производительности, который может обеспечить браузер, с минимальными усилиями со стороны вас как разработчика.
Свойство content-visibility принимает несколько значений, но значение auto
обеспечивает немедленное повышение производительности. Элемент с content-visibility: auto
получает layout
, style
и включение paint
. Если элемент находится за пределами экрана (и не имеет никакого отношения к пользователю другим образом — релевантными элементами будут те, которые имеют фокус или выделение в своем поддереве), он также получает ограничение size
(и перестает рисовать и проверять его содержимое).
Что это значит? Короче говоря, если элемент находится за пределами экрана, его потомки не отображаются. Браузер определяет размер элемента, не принимая во внимание его содержимое, и на этом останавливается. Большая часть рендеринга, такая как стилизация и расположение поддерева элемента, пропускается.
Когда элемент приближается к области просмотра, браузер больше не добавляет ограничение size
и начинает рисовать и проверять содержимое элемента. Это позволяет выполнить работу по рендерингу как раз вовремя, чтобы пользователь мог ее увидеть.
Примечание о доступности
Одной из особенностей content-visibility: auto
является то, что содержимое за кадром остается доступным в объектной модели документа и, следовательно, в дереве доступности (в отличие от visibility: hidden
). Это означает, что контент можно искать на странице и переходить к нему, не дожидаясь его загрузки и не жертвуя производительностью рендеринга.
Однако обратной стороной этого является то, что элементы -ориентиры с такими функциями стиля, как display: none
или visibility: hidden
также будут отображаться в дереве специальных возможностей, когда они находятся за пределами экрана, поскольку браузер не будет отображать эти стили до тех пор, пока они не войдут в область видимости. окно просмотра. Чтобы они не были видны в дереве доступности и не могли вызвать беспорядок, обязательно добавьте также aria-hidden="true"
.
Пример: блог о путешествиях.
Блог о путешествиях обычно содержит набор историй с несколькими изображениями и описательным текстом. Вот что происходит в обычном браузере при переходе на блог о путешествиях:
- Часть страницы загружается из сети вместе со всеми необходимыми ресурсами.
- Браузер стилизует и размещает все содержимое страницы, не учитывая, видно ли это содержимое пользователю.
- Браузер возвращается к шагу 1, пока не будут загружены все страницы и ресурсы.
На шаге 2 браузер обрабатывает все содержимое в поисках того, что могло измениться. Он обновляет стиль и макет всех новых элементов, а также элементов, которые могли измениться в результате новых обновлений. Это работа по рендерингу. Это требует времени.
Теперь представьте, что произойдет, если вы установите content-visibility: auto
для каждой отдельной истории в блоге. Общий цикл тот же: браузер загружает и отображает фрагменты страницы. Однако разница заключается в объеме работы, которую он выполняет на этапе 2.
Благодаря видимости контента он будет стилизовать и размещать все содержимое, которое в данный момент видно пользователю (оно находится на экране). Однако при обработке истории, которая полностью находится за кадром, браузер пропустит работу по рендерингу и только стилизует и разметит сам блок элемента.
Производительность загрузки этой страницы будет такая, как если бы она содержала полные экранные истории и пустые поля для каждой из закадровых историй. Это работает намного лучше, с ожидаемым снижением затрат на рендеринг при загрузке на 50% или более . В нашем примере мы видим увеличение времени рендеринга с 232 мс до 30 мс . Это семикратный прирост производительности.
Какую работу вам нужно проделать, чтобы воспользоваться этими преимуществами? Сначала мы разбиваем контент на разделы:
Затем мы применяем к разделам следующее правило стиля:
.story {
content-visibility: auto;
contain-intrinsic-size: 1000px; /* Explained in the next section. */
}
Укажите естественный размер элемента с помощью contain-intrinsic-size
Чтобы реализовать потенциальные преимущества content-visibility
, браузеру необходимо применить ограничение размера, чтобы гарантировать, что результаты рендеринга содержимого никоим образом не влияют на размер элемента. Это означает, что элемент будет располагаться так, как если бы он был пустым. Если элемент не имеет высоты, указанной в обычном блочном макете, то его высота будет равна 0.
Это может быть не идеально, поскольку размер полосы прокрутки будет меняться в зависимости от того, что каждая история имеет ненулевую высоту.
К счастью, CSS предоставляет еще одно свойство, contain-intrinsic-size
, которое эффективно определяет естественный размер элемента, если на элемент влияет ограничение размера . В нашем примере мы устанавливаем значение 1000px
в качестве оценки высоты и ширины разделов.
Это означает, что он будет располагаться так, как если бы у него был один дочерний элемент с размерами «внутреннего размера», гарантируя, что ваши неразмерные элементы div по-прежнему будут занимать место. contain-intrinsic-size
действует как размер заполнителя вместо отображаемого контента.
Ключевое слово auto
для contain-intrinsic-size
приводит к тому, что браузер запоминает последний отображаемый размер, если таковой имеется, и использует его вместо размера заполнителя, предоставленного разработчиком. Например, если вы указали contain-intrinsic-size: auto 300px
, элемент начнет иметь внутренний размер 300px
в каждом измерении, но как только содержимое элемента будет визуализировано, он сохранит визуализированный внутренний размер. Любые последующие изменения размера рендеринга также будут запомнены. На практике это означает, что если вы прокрутите элемент с применением content-visibility: auto
, а затем прокрутите его обратно за пределы экрана, он автоматически сохранит идеальную ширину и высоту и не вернется к размеру заполнителя. Эта функция особенно полезна для бесконечных скроллеров, которые теперь могут автоматически улучшать оценку размера с течением времени по мере того, как пользователь исследует страницу.
Скройте контент с помощью content-visibility: hidden
Что, если вы хотите, чтобы контент оставался необработанным независимо от того, отображается он на экране или нет, используя при этом преимущества кэшированного состояния рендеринга? Введите: content-visibility: hidden
.
Свойство content-visibility: hidden
дает вам все те же преимущества неотрисованного контента и кэшированного состояния рендеринга, что и content-visibility: auto
за пределами экрана. Однако, в отличие от auto
, он не начинает автоматически рендеринг на экране.
Это дает вам больше контроля, позволяя скрыть содержимое элемента, а затем быстро его отобразить.
Сравните его с другими распространенными способами сокрытия содержимого элемента:
-
display: none
: скрывает элемент и уничтожает его состояние рендеринга. Это означает, что отобразить элемент так же дорого, как отобразить новый элемент с тем же содержимым. -
visibility: hidden
: скрывает элемент и сохраняет его состояние рендеринга. На самом деле это не удаляет элемент из документа, поскольку он (и его поддерево) по-прежнему занимает геометрическое пространство на странице, и на него по-прежнему можно щелкнуть. Он также обновляет состояние рендеринга в любое время, даже если оно скрыто.
content-visibility: hidden
, с другой стороны, скрывает элемент, сохраняя при этом состояние его рендеринга, поэтому, если есть какие-либо изменения, которые должны произойти, они происходят только тогда, когда элемент отображается снова (т.е. свойство content-visibility: hidden
удаляется).
Некоторые отличные варианты использования content-visibility: hidden
— при реализации расширенных виртуальных скроллеров и измерении макета. Они также отлично подходят для одностраничных приложений (SPA). Неактивные представления приложений можно оставить в DOM с помощью content-visibility: hidden
, чтобы предотвратить их отображение, но сохранить их кэшированное состояние. Это ускоряет визуализацию представления, когда оно снова становится активным.
Влияние на взаимодействие со следующей отрисовкой (INP)
INP — это показатель, который оценивает способность страницы надежно реагировать на ввод пользователя. На скорость отклика может повлиять любой чрезмерный объем работы, выполняемой в основном потоке, включая работу по рендерингу.
Всякий раз, когда вы можете сократить объем работы по рендерингу на какой-либо странице, вы даете основному потоку возможность быстрее реагировать на вводимые пользователем данные. Это включает в себя работу по рендерингу, а использование CSS-свойства content-visiblity
, где это необходимо, может сократить работу по рендерингу, особенно во время запуска, когда большая часть работы по рендерингу и макету уже выполнена.
Сокращение работы по рендерингу напрямую влияет на INP. Когда пользователи пытаются взаимодействовать со страницей, которая правильно использует свойство content-visibility
, чтобы отложить макет и рендеринг закадровых элементов, вы даете основному потоку возможность отреагировать на критически важную работу, видимую пользователем. В некоторых ситуациях это может улучшить INP вашей страницы.
Заключение
content-visibility
и спецификация CSS Containment Spec означают, что ваш CSS-файл получит впечатляющее повышение производительности. Для получения дополнительной информации об этих свойствах посетите: