Критический путь рендеринга — это шаги, выполняемые до тех пор, пока веб-страница не начнет рендериться в браузере. Для рендеринга страниц браузерам необходим сам HTML-документ, а также все критически важные ресурсы, необходимые для рендеринга этого документа.
Получение HTML-документа в браузер было рассмотрено в предыдущем модуле «Общие вопросы производительности HTML» . Однако в этом модуле мы подробнее рассмотрим, что делает браузер после загрузки HTML-документа для отображения страницы.
Прогрессивный рендеринг
Сеть распространяется по своей природе. В отличие от собственных приложений, которые устанавливаются перед использованием, браузеры не могут зависеть от наличия у веб-сайтов всех ресурсов, необходимых для отображения страницы. Таким образом, браузеры очень хорошо справляются с постепенной отрисовкой страниц. Нативные приложения обычно проходят этап установки, а затем этап запуска. Однако для веб-страниц и веб-приложений границы между этими двумя этапами гораздо менее четкие, и браузеры были специально разработаны с учетом этого.
Как только у браузера появляются ресурсы для отображения страницы, он обычно начинает это делать. Таким образом, выбор становится о том , когда рендерить: когда слишком рано?
Если браузер выполняет рендеринг как можно быстрее, когда у него есть только HTML, но до того, как у него появится CSS или необходимый JavaScript, то страница на мгновение будет выглядеть сломанной и значительно изменится к окончательному рендерингу. Это хуже, чем первоначальное представление пустого экрана на некоторое время, пока у браузера не будет больше ресурсов, необходимых для первоначального рендеринга, обеспечивающего лучший пользовательский опыт.
С другой стороны, если браузер ждет доступности всех ресурсов вместо последовательного рендеринга, пользователю придется ждать долгое время; часто без необходимости, если страницу можно было использовать гораздо раньше.
Браузеру необходимо знать, какое минимальное количество ресурсов ему следует ожидать, чтобы избежать явно некорректного взаимодействия. С другой стороны, браузер также не должен ждать дольше, чем необходимо, прежде чем предоставить пользователю какой-либо контент. Последовательность шагов, которые браузер выполняет перед выполнением первоначального рендеринга, называется критическим путем рендеринга .
Понимание критического пути рендеринга может помочь улучшить веб-производительность, гарантируя, что вы не будете блокировать отрисовку начальной страницы больше, чем это необходимо. В то же время, однако, важно также не допускать слишком раннего выполнения рендеринга, удаляя необходимые ресурсы для этого первоначального рендеринга из критического пути рендеринга.
(Критический) путь рендеринга
Путь рендеринга включает в себя следующие шаги:
- Построение объектной модели документа (DOM) из HTML.
- Построение объектной модели CSS (CSSOM) на основе CSS.
- Применение любого JavaScript, который изменяет DOM или CSSOM.
- Построение дерева рендеринга из DOM и CSSOM.
- Выполняйте операции со стилем и макетом на странице, чтобы увидеть, какие элементы и где подходят.
- Рисуйте пиксели элементов в памяти.
- Объедините пиксели, если какой-либо из них перекрывается.
- Физически выведите все полученные пиксели на экран.
Только после выполнения всех этих шагов пользователь увидит контент на экране.
Этот процесс рендеринга происходит несколько раз. Первоначальный рендеринг вызывает этот процесс, но по мере того, как становятся доступными дополнительные ресурсы, влияющие на рендеринг страницы, браузер повторно запускает этот процесс — или, возможно, только его части — чтобы обновить то, что видит пользователь. Критический путь рендеринга фокусируется на процессе, ранее описанном для первоначального рендеринга, и зависит от необходимых для него критических ресурсов.
Какие ресурсы находятся на критическом пути рендеринга?
Браузеру необходимо дождаться загрузки некоторых критически важных ресурсов, прежде чем он сможет завершить первоначальный рендеринг. Эти ресурсы включают в себя:
- Часть HTML.
- CSS, блокирующий рендеринг, в элементе
<head>
. - Блокирующий рендеринг JavaScript в элементе
<head>
.
Ключевым моментом является то, что браузер обрабатывает HTML в потоковом режиме. Как только браузер получает какую-либо часть HTML-кода страницы, он начинает ее обрабатывать. Тогда браузер может — и часто так и делает — решить отобразить его задолго до получения остальной части HTML-кода страницы.
Важно отметить, что для первоначального рендеринга браузер обычно не ждет:
- Весь HTML.
- Шрифты.
- Изображения.
- JavaScript, не блокирующий рендеринг, за пределами элемента
<head>
(например, элементы<script>
расположенные в конце HTML). - CSS, не блокирующий рендеринг, за пределами элемента
<head>
или CSS со значениемmedia
атрибута , который не применяется к текущему экрану просмотра.
Шрифты и изображения часто рассматриваются браузером как контент, который необходимо заполнить во время последующих повторных отрисовок страниц, поэтому им не нужно задерживать первоначальный рендеринг. Однако это может означать, что при первоначальном рендеринге остаются пустые области, пока текст скрыт в ожидании шрифтов или пока не станут доступны изображения. Еще хуже то, что для определенных типов контента не зарезервировано достаточно места — особенно если размеры изображения не указаны в HTML — макет страницы может измениться при последующей загрузке этого контента. Этот аспект пользовательского опыта измеряется с помощью метрики Cumulative Layout Shift (CLS) .
Элемент <head>
является ключевым для обработки критического пути рендеринга. Настолько, что в следующем разделе это рассматривается более подробно . Оптимизация содержимого элемента <head>
— ключевой аспект веб-производительности. Однако, чтобы понять критический путь рендеринга на данный момент, вам нужно только знать, что элемент <head>
содержит метаданные о странице и ее ресурсах, но не содержит фактического контента, который может видеть пользователь. Видимый контент содержится в элементе <body>
, который следует за элементом <head>
. Прежде чем браузер сможет отображать какой-либо контент, ему необходимы как сам контент, так и метаданные о том, как его отображать.
Однако не все ресурсы, указанные в элементе <head>
, строго необходимы для отрисовки начальной страницы, поэтому браузер ожидает только те ресурсы, которые необходимы. Чтобы определить, какие ресурсы находятся на критическом пути рендеринга, вам необходимо понимать CSS и JavaScript, блокирующие рендеринг и блокирующий синтаксический анализатор.
Ресурсы, блокирующие рендеринг
Некоторые ресурсы считаются настолько важными, что браузер приостанавливает рендеринг страницы, пока не обработает их. CSS попадает в эту категорию по умолчанию.
Когда браузер видит CSS — будь то встроенный CSS в элементе <style>
или внешний ресурс, на который ссылается элемент <link rel=stylesheet href="...">
— браузер избегает рендеринга какого-либо контента до тех пор, пока он не будет завершил загрузку и обработку этого CSS.
Тот факт, что ресурс блокирует рендеринг, не обязательно означает, что он не позволяет браузеру делать что-либо еще. Браузеры стараются быть максимально эффективными, поэтому, когда браузер видит, что ему необходимо загрузить ресурс CSS, он запрашивает его и приостанавливает рендеринг , но продолжает обрабатывать остальную часть HTML и ищет другую работу, которую можно выполнить в тем временем.
Ресурсы, блокирующие рендеринг, такие как CSS, используются для блокировки всего рендеринга страницы при их обнаружении. Это означает, что блокирует ли какой-либо CSS рендеринг или нет, зависит от того, обнаружил ли его браузер. Некоторые браузеры ( первоначально Firefox , а теперь и Chrome ) блокируют рендеринг только контента ниже ресурса, блокирующего рендеринг. Это означает, что для критического пути блокировки рендеринга нас обычно интересуют ресурсы блокировки рендеринга в <head>
, поскольку они эффективно блокируют рендеринг всей страницы.
Более недавнее нововведение — атрибутblocking blocking=render
, добавленный в Chrome 105 . Это позволяет разработчикам явно помечать элемент <link>
, <script>
или <style>
как блокирующий рендеринг до тех пор, пока элемент не будет обработан, но тем временем позволяет парсеру продолжать обработку документа.
Ресурсы, блокирующие парсер
Ресурсы, блокирующие парсер, — это те, которые не позволяют браузеру искать другую работу, продолжая анализировать HTML. JavaScript по умолчанию блокирует парсер (если специально не помечен как асинхронный или отложенный ), поскольку JavaScript может изменить DOM или CSSOM при своем выполнении. Таким образом, браузер не может продолжать обработку других ресурсов, пока не узнает полное влияние запрошенного JavaScript на HTML-код страницы. Поэтому синхронный JavaScript блокирует синтаксический анализатор.
Ресурсы, блокирующие парсер, по сути, также блокируют рендеринг. Поскольку анализатор не может продолжить работу с блокирующим синтаксический анализ ресурсом до тех пор, пока он не будет полностью обработан, он не может получить доступ к содержимому после него и отобразить его. Браузер может отображать любой полученный HTML-код, пока он ожидает, но что касается критического пути рендеринга, любые ресурсы, блокирующие парсер в <head>
фактически означают, что весь контент страницы блокируется от рендеринга.
Блокировка синтаксического анализатора может привести к огромным потерям производительности — гораздо больше, чем просто блокировка рендеринга. По этой причине браузеры будут пытаться снизить эти затраты, используя вторичный анализатор HTML, известный как сканер предварительной загрузки , для загрузки предстоящих ресурсов, пока основной анализатор HTML заблокирован. Хотя это не так хорошо, как фактический анализ HTML, он, по крайней мере, позволяет сетевым функциям браузера работать раньше заблокированного синтаксического анализатора, а это означает, что вероятность повторной блокировки в будущем будет меньше.
Определить блокирующие ресурсы
Многие инструменты аудита производительности определяют ресурсы рендеринга и блокировки синтаксического анализатора. WebPageTest помечает ресурсы, блокирующие рендеринг, оранжевым кружком слева от URL-адреса ресурса:
Все ресурсы, блокирующие рендеринг, необходимо загрузить и обработать до начала рендеринга, что отмечено сплошной темно-зеленой линией в водопаде.
Lighthouse также выделяет ресурсы, блокирующие рендеринг, но более тонким способом и только в том случае, если ресурс действительно задерживает рендеринг страницы. Это может быть полезно, чтобы избежать ложных срабатываний, когда вы в противном случае минимизируете блокировку рендеринга. Запуск того же URL-адреса страницы, что и на предыдущем рисунке WebPageTest, через Lighthouse идентифицирует только одну из таблиц стилей как ресурс, блокирующий рендеринг.
Оптимизируйте критический путь рендеринга
Оптимизация критического пути рендеринга предполагает сокращение времени получения HTML (представленного метрикой «Время до первого байта» (TTFB) ), как подробно описано в предыдущем модуле, а также снижение влияния ресурсов, блокирующих рендеринг. Эти концепции изучаются в следующих модулях.
Критический путь рендеринга контента
В течение долгого времени критический путь рендеринга был связан с первоначальным рендерингом. Однако появились более ориентированные на пользователя показатели веб-производительности, что вызывает некоторые сомнения, должна ли конечная точка критического пути рендеринга быть самой первой отрисовкой или одной из наиболее содержательных отрисовок, которые следуют за ней.
Альтернативный подход — вместо этого сосредоточиться на времени до наибольшей отрисовки содержимого (LCP) — или даже первой отрисовки содержимого (FCP) — как части пути рендеринга содержимого (или ключевого пути , как его могут назвать другие). В этом случае вам может потребоваться включить ресурсы, которые не обязательно являются блокирующими (как это было типичное определение критического пути рендеринга), но необходимы для рендеринга содержательных отрисовок.
Независимо от вашего точного определения того, что вы определяете как «критическое», важно понимать, что сдерживает любой первоначальный рендеринг и ваш ключевой контент. Первая отрисовка измеряет первую возможную возможность отрисовать что-либо для пользователя. В идеале это должно быть что-то значимое, а не что-то вроде цвета фона, например, — но даже если оно не содержит содержания, представление чего-либо пользователю все равно имеет смысл, что является аргументом в пользу измерения критического пути рендеринга, как это было сделано ранее. традиционно определяется. В то же время важно также измерить, когда основной контент представлен пользователю.
Определите путь рендеринга контента
Многие инструменты могут идентифицировать элементы LCP и время их рендеринга. Помимо элемента LCP , Lighthouse также поможет определить этапы LCP и время, затрачиваемое на каждый из них, чтобы помочь вам понять, на чем лучше всего сосредоточить усилия по оптимизации:
Для более сложных сайтов Lighthouse также выделяет цепочки критических запросов в отдельный аудит:
Этот аудит Lighthouse отслеживает все ресурсы, загруженные с высоким приоритетом, поэтому он включает веб-шрифты и другой контент, который Chrome устанавливает как ресурс с высоким приоритетом, даже если он на самом деле не блокирует рендеринг.
Проверьте свои знания
Что означает критический путь рендеринга?
Какие ресурсы участвуют в критическом пути рендеринга?
<head>
.<head>
.Почему блокировка рендеринга является необходимой частью рендеринга страницы?
Почему JavaScript блокирует анализатор HTML (при условии, что атрибуты defer
, async
или module
не указаны в элементе <script>
)?
<script>
блокирует синтаксический анализатор и блокирует рендеринг.Далее: Оптимизация загрузки ресурсов
В этом модуле рассмотрены некоторые теоретические аспекты того, как браузер отображает веб-страницу, и, в частности, что необходимо для завершения первоначального рендеринга страницы. В следующем модуле рассматривается, как можно оптимизировать этот путь рендеринга, изучая, как оптимизировать загрузку ресурсов .