Если CSS блокирует рендеринг, почему мы видим FOUC?

Чтобы построить дерево рендеринга, браузер требует DOM и CSSOM. CSSOM может быть создан только после загрузки CSS. По сути, как только CSS загружен, страница должна быть отображена правильно. Но почему мы видим Flash Of Unstyled Content(FOUC) на странице? В каком временном окне браузер показывает неустановленный контент?

Пожалуйста, помогите мне понять это.

Ссылка: https://developers.google.com/web/fundamentals/performance/critical-rendering-path/render-blocking-css

4 ответа

Решение

Это должно помочь.

  1. ДОМ построен
  2. Если мы все еще ждем создания CSSOM, то увидим FOUC
  3. CSSOM построен
  4. DOM и CSSOM объединяются в дерево рендеринга, которое отображает DOM с помощью CSS (стилизованный контент)

Таким образом, браузер показывает FOUC при ожидании CSS. Как только CSS загружен, DOM и CSSOM объединяются в одно дерево, которое называется Render Tree, и это стилизованный контент.

Согласно статье Google, сайт NY Times показывает FOUC до тех пор, пока не будет создан CSSOM, а затем визуализируется дерево рендеринга. Это демонстрирует, что рендеринг дерева рендеринга отличается от рендеринга дерева DOM. Дерево DOM отображается, но выгруженный CSS блокирует отображение дерева рендеринга (обратите внимание на разницу). Вот почему FOUC показывает до того, как CSS разблокирован, а дерево рендеринга показывает

На мой взгляд, это самый полный разговор на эту тему от Дэвида Барона, главного инженера Mozilla: https://vimeo.com/103108124

Я все еще не согласен с принятым ответом, потому что согласно критическому пути рендеринга при нормальных обстоятельствах ничто не может быть нарисовано на экране, пока не будет построено дерево рендеринга (DOM + CSSOM).

Я считаю, что эта статья Google несколько сбивает с толку на первый взгляд, но она становится менее противоречивой, если мы внимательно рассмотрим следующее утверждение:

"Что произойдет, если мы попытаемся отобразить типичную страницу без блокировки отрисовки в CSS?". (Далее следует NY Times FOUC в качестве примера поведения без блокировки рендеринга.)

Дело в том, что исторически FOUC происходил по разным причинам в разных версиях браузеров и при разных обстоятельствах.

Например, согласно этой древней статье, мы могли столкнуться с FOUC в веб-наборе, если бы какой-то JS попытался получить доступ к свойствам, которые имеют информацию о макете / стиле.

Web Kit имеет противоположное поведение и будет продолжать анализ страницы даже после обнаружения директивы таблицы стилей, чтобы можно было распараллелить загрузку таблицы стилей и скриптов. Таким образом, все будет готово к отображению гораздо раньше.

Проблема с таким поведением заключается в том, что делать, когда сценарий пытается получить доступ к свойству, которое требует для ответа точной информации о макете / стиле. Текущее поведение Safari при отправке, когда это происходит, выглядит следующим образом: он продолжит и выложит то, что у него есть, даже если у него еще нет таблицы стилей. Он также отобразит это. Это означает, что вы видите FOUC всякий раз, когда сценарий пытается получить доступ к таким свойствам, как scrollHeight или offsetWidth, до загрузки таблицы стилей.

Поэтому, когда мы говорим "FOUC происходит", должны быть объяснения, при каких обстоятельствах и в каком браузере это происходит, потому что это не "просто" происходит везде.

Основная причина FOUC заключается в том, что новые/другие стили применяются после того, как элементы уже были нарисованы на экране.

Теперь возникает вопрос -> может ли FOUC произойти, когда страница загружается, а сама разметка страницы включает <link>для внешнего css, на высоком уровне кажется, что этого не должно происходить, поскольку css блокирует рендеринг, и не должно быть случая, когда какой-либо элемент может отображаться без его вычисляемых стилей, но это (FOUC) происходит при загрузке страницы в определенных условиях.

Основная причина этого заключается в том, что построение дерева dom является инкрементным, т.е. без полной html-разметки браузер может отображать частичный html, что бы ни было загружено до заданного момента времени.

Чтобы понять это, давайте возьмем пример следующего html -

      <!DOCTYPE html>
<html lang="en">
  <body>
    <100 html tags block 1 />
    <link href="css1" />
    <100 html tags block 2 />
    <link href="css2" />
    <100 html tags block 3 />
    <link href="css3" />
  </body>
</html>
  1. Первые 100 тегов преобразуются в dom и с помощью существующего cssom (который был создан из таблиц стилей пользовательского агента) формируют дерево рендеринга, которое будет нарисовано и будет видно пользователю.
  2. После этого синтаксический анализ будет заблокирован до загрузки css1 и создания нового cssom со стилями useragent+css1.
  3. И с новым деревом рендеринга (сформированным через старый dom + новый cssom) блок 1 html будет обновлен (FOUC)
  4. Затем блок html 2 обрабатывается аналогичным образом по мере его загрузки после этого.
  5. Теперь то же самое, что и шаг 3, повторяется с блоком 2 и блоком 3.
  6. И то же самое продолжается до конца документа

Кредиты - https://medium.com/jspoint/how-the-browser-renders-a-web-page-dom-cssom-and-rendering-df10531c9969

Вам необходимо внимательно прочитать статью:

Приведенный выше пример, показывающий веб-сайт NYTimes с CSS и без него, демонстрирует, почему рендеринг блокируется до тех пор, пока CSS не доступен — без CSS страница практически непригодна для использования.

Скриншот — это не то, что на самом деле происходит в браузерах, он предназначен для демонстрации того, что произошло бы, если бы CSS не блокировал рендеринг. Ваше первоначальное понимание верно: FOUC невозможен при нормальных обстоятельствах. Однако если вы применяете дополнительные стили позже на странице или с помощью Javascript, вам необходимо убедиться, что они вводятся до того, как какой-либо HTML-код, на который эти стили влияют, во избежание FOUC.

Другие вопросы по тегам