Как CSS блокирует рендеринг? - PullRequest
1 голос
/ 20 марта 2020

Я все еще не могу понять эту концепцию "CSS блокирует рендеринг" очень четко. Я очень хорошо понимаю, как JS блокирует парсер. Но первое мне все еще немного неясно.

Давайте рассмотрим пример:

index. html:

<!DOCTYPE html>
<html>
<head>
  <title>Some Document</title>
  <link href='cdn1.com/styles1.css' rel="stylesheet"/>
  <link href='cdn2.com/styles2.css' rel="stylesheet"/>
</head>
<body>
   ...
   ...
</body>
</html>

style1. css (из cdn1):

body { background: blue }

style2. css (из cdn2):

body { background: red }

Теперь давайте предположим, что style1. css из cdn1 потребовал 1 se c для загрузки, тогда как style2 из cdn2 занял 500ms . Я хочу знать, что все увидит конечный пользователь в браузере между следующей временной шкалой:

  1. во время T <500 мс: </strong> Будет ли FOU C или пустая страница, так как CSS блокирует рендеринг, и дерево рендеринга не будет создаваться, пока у нас не будет style1. css file
  2. во время 500ms Будет ли красная страница (поскольку style2. css уже загружена), FOU C или пустая страница по причине, указанной в пункте 1.

Кроме того, будет ли результат одинаковым для всех браузеров, в первую очередь для Edge, Chrome, Firefox и Safari?

Ответы [ 2 ]

1 голос
/ 21 марта 2020

В следующих примерах используются ресурсы, которые намеренно задерживаются, чтобы показать, что происходит. Поскольку он использует динамические c ресурсы, чтобы каждый раз показывать разные идентификаторы и обеспечивать очистку кэша, я не могу использовать фрагмент стека, но я покажу вам критический код и ссылку на рабочий пример.

В первом примере у нас есть описанный вами случай.

<!DOCTYPE html>
<html>
<head>
  <title>Render Blocking Test - A</title>
  <link href='/css/styles1.css?delay=1000&x={cachebuster}' rel="stylesheet"/>
  <link href='/css/styles2.css?delay=5000&x={cachebuster}' rel="stylesheet"/>
</head>
<body>
   <h1>Render Blocking Test - A</h1>
   <b>{cachebuster}</b>
</body>
</html>

Заполнитель "{cachebuster}" заменяется другим GUID каждый refre sh. Задержки для двух ресурсов CSS составляют 1 секунду и 5 секунд, чтобы более четко показать задержки

styles1. css содержит

body { background: blue }

styles2. css содержит

body { background: red }

Посмотрите, как это работает здесь: http://alohci.net/text/html/render-blocking-a.htm

Вы увидите, что страница пуста, пока не пройдут 5 секунд, и все ресурсы css скачал. Или при refre sh предыдущая страница отображается, пока не пройдет 5 секунд (GUID изменится через 5 секунд). Фон, когда появляется новый контент, сразу становится красным, а не белым или синим. Вот что означает блокировка рендеринга - новый рендеринг страницы не выполняется до тех пор, пока не будут доступны ресурсы, блокирующие рендеринг.


Для сравнения см. Этот второй пример.

<!DOCTYPE html>
<html>
<head>
  <title>Render Blocking Test - B</title>
  <link href='/css/styles1.css?delay=1000&x={cachebuster}' rel="stylesheet"/>
</head>
<body>
   <h1>Render Blocking Test - B</h1>
   <b>{cachebuster}</b>
   <script src="/js/script1.js?delay=4000&x={cachebuster}"></script>
   <link href='/css/styles2.css?delay=5000&x={cachebuster}' rel="stylesheet"/>
</body>
</html>

Вот как это работает: http://alohci.net/text/html/render-blocking-b.htm

Здесь у нас есть один ресурс блокировки рендеринга на одну секунду, затем некоторый контент - заголовок и GUID - затем скрипт загрузка занимает 4 секунды, а затем второй ресурс блокировки рендеринга.

В этом случае текст и синий фон появляются через 1 секунду. Скрипт загружает парсер-блоки, поэтому второй ресурс css еще не проанализирован и поэтому не может блокировать рендеринг. Следовательно, синий фон виден. Затем скрипт загружается, второй ресурс css анализируется и выполняет рендеринг-блоки до тех пор, пока он тоже не будет загружен, после чего фон меняется с синего на красный.

Наконец, вы можете заметить, что требуется только 5 секунд для появления красного фона, а не 9 секунд, как вы можете себе представить. Это потому, что синтаксический анализатор может по-прежнему смотреть в будущее, когда он блокирован, следует признать, что ему, вероятно, потребуется загрузить второй ресурс css и забрать его заблаговременно, даже если он не сможет использовать его, пока анализатор не разблокируется.

0 голосов
/ 20 марта 2020

Что вам нужно знать, это «CSS Объектная модель». Рендеринг CSS не такой, как у JS. Когда все CSS загружены, создается «главное дерево», и принимается решение, что для всех inline CSS, internal CSS, external CSS - какие будут окончательные правила, которые будут применяться.

Это окончательное дерево известно как https://developer.mozilla.org/en-US/docs/Web/API/CSS_Object_Model

Преимущество использования SPA (одностраничного приложения), например Angular, React, Vue и др. c. является то, что вся страница не обновляется, поэтому различные шаги, такие как:

  1. Перезагрузка HTML Dom
  2. Перезагрузка CSS Файлы
  3. Создание "CSS Объектная модель "
  4. Отображение" этой CSS модели "в HTML -Doms

сохраняется, поэтому они быстрее.

  • Надеюсь, это немного поможет!
...