Как CSS применяется браузером и подвержен ли репликации?
Скажем, у нас есть HTML-страница с одной таблицей стилей <link>
. Как браузер принимает правила в этой таблице стилей и применяет их к HTML? Я не спрашиваю, как сделать это быстрее, я хочу знать, как обрабатывается сам рендеринг.
Использует ли оно каждое правило один за другим, когда оно анализирует таблицу стилей и последовательно производит результат? Или, полностью ли загружено содержимое файла CSS, затем полностью оценивается, а затем сразу применяется к HTML? Или что-то еще?
Я прошу об этом после публикации ответа на вопрос о порядке правил CSS, влияющий на скорость рендеринга, при условии, что стили были отображены в качестве загруженной таблицы стилей, поэтому первые правила будут применяться до последних, и не все сразу. Я не уверен, где я взял эту идею, это то, что я всегда думал.
Я попробовал демонстрацию на своем сервере, которая выглядела так:
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
<link rel="stylesheet" href="test.css" />
</head>
<body></body>
</html>
test.css
Содержание:
html { background:green }
/* thousands of lines of irrelevant CSS to make the download slow */
html { background:red }
Тестирование в Firefox 5, я ожидал сначала увидеть зеленый цвет, а затем перейти к красному. Этого не произошло. Я попытался с двумя отдельными таблицами стилей с противоречивыми правилами и получил те же результаты. После многих комбинаций единственным способом заставить его работать был встроенный блок <style>
в <head>
, с конфликтующими правилами, исходящими от <link>
в <body>
(само тело было полностью пустым, за исключением тег ссылки). Даже используя встроенный атрибут style
в теге <html>
, а затем загрузка этой таблицы стилей не создала мерцание, которое я ожидал.
Являются ли repaints каким-либо образом затронуты CSS, или это конечный результат, который применяется сразу после загрузки всей таблицы стилей, и он вычисляет правила для конечного результата? Файлы CSS загружаются в паралоге с самим HTML или блокируют его (например, теги script)? Как это работает?
Я не ищу советы по оптимизации, я ищу авторитетные ссылки на эту тему, чтобы я мог привести их в будущем. Было очень сложно искать эту информацию, не внося тонны несвязанного материала. Краткое описание:
- Загружается ли весь контент CSS до того, как он будет применен? (обратитесь пожалуйста)
- Как это влияет на такие вещи, как
@import
, несколько <link>
s, встроенные атрибуты стиля, <style>
блоки в голове и разные механизмы рендеринга?
- Загружает ли содержимое CSS-содержимого загрузку самого документа HTML?
Ответы
Ответ 1
Как браузер применяет правила в этой таблице стилей и применяет его к HTML?
Обычно это выполняется потоковым способом. Браузер читает теги HTML как поток и применяет какие правила он может к элементам, которые он видел до сих пор. (Очевидно, это упрощение.)
Интересный связанный Q & A: Используйте селектор CSS для сбора элементов HTML из потокового анализатора (например, поток SAX) (отклонение при поиске статья, которую я имею в виду).
А, вот он: Почему у нас нет родительского селектора.
Мы часто думаем о наших страницах как о полных и полных документах, полных элементов и контента. Однако браузеры предназначены для обработки документов, таких как поток. Они начинают получать документ с сервера и могут отображать документ до его полной загрузки. Каждый node оценивается и отображается в окне просмотра по мере его получения.
Взгляните на тело примерного документа:
<body>
<div id="content">
<div class="module intro">
<p>Lorem Ipsum</p>
</div>
<div class="module">
<p>Lorem Ipsum</p>
<p>Lorem Ipsum</p>
<p>Lorem Ipsum <span>Test</span></p>
</div>
</div>
</body>
Браузер начинается сверху и видит элемент body
. С этой точки зрения, он думает, что он пуст. Он ничего не оценил. Браузер определит, что вычисленные стили, и примените их к элемент. Каков шрифт, цвет, высота линии? После этого рисует это, он рисует его на экране.
Затем он видит элемент div
с идентификатором content
. Опять же, при этом точка, он думает, что он пуст. Он ничего не оценил. браузер определяет стили, а затем div
нарисован. браузер определит, нужно ли перекрасить тело - сделал ли этот элемент шире или выше? (Я подозреваю, что есть другие соображения, но изменения ширины и высоты являются наиболее распространенными эффектами дочерних элементов иметь на своих родителей.)
Этот процесс продолжается до тех пор, пока он не достигнет конца документа.
![pc7vG.png]()
CSS оценивается справа налево.
Чтобы определить, применяется ли правило CSS к определенному элементу, оно начинается справа от правила и работает влево.
Если у вас есть правило вроде body div#content p { color: #003366; }
, тогда для каждого элемента - поскольку он отображается на странице - сначала спросите, если это элемент абзаца. Если это так, то он пробивается вверх по DOM и спросите, есть ли div
с идентификатором содержимого. Если он найдет то, что он ищет поскольку он продолжит свой путь до DOM, пока не достигнет значения body
.
Работая справа налево, браузер может определить, является ли правило применяется к этому конкретному элементу, который он пытается viewport намного быстрее. Чтобы определить, какое правило более или менее вы должны выяснить, сколько узлов нужно оценивать чтобы определить, может ли стиль применяться к элементу.
Итак, почему контент стилей не применялся постепенно (зеленый, затем красный)?
Я думаю, что ответ заключается в том, что внешние таблицы стилей анализируются по мере их загрузки, но не применяются до тех пор, пока все таблицы стилей не будут проанализированы. Разумеется, при анализе таблицы стилей браузер оптимизирует ненужные и избыточные правила CSS.
У меня нет никаких доказательств, чтобы поддержать это прямо сейчас, но это объяснение кажется разумным для меня и согласуется с тем, что вы видите, как с внешними, так и с встроенными стилями.
Ответ 2
Первым и самым важным для понимания является то, что браузеры не могут начать рисовать страницу до тех пор, пока не будет загружен весь CSS. (Имейте в виду, что спецификация W3C говорит, что ссылки CSS разрешены только в голове, поэтому, когда вы начинаете ссылаться на таблицы стилей в теге body, как и вы, разные браузеры будут обрабатывать эту ситуацию по-другому.)
Теперь веб-страницу читается как поток, а правила CSS применяются к элементам HTML, поскольку они попадают на страницу. Чтобы процитировать статью Google, указанную ниже:
Когда браузер анализирует HTML, он создает внутреннее дерево документов, представляющее все элементы, которые будут отображаться. Затем он сопоставляет элементы со стилями, указанными в разных таблицах стилей, в соответствии со стандартными правилами каскада CSS, наследования и упорядочения.
Итак, чтобы ответить на ваши вопросы:
Использует ли оно каждое правило один за другим, когда оно анализирует таблицу стилей и последовательно производит результат? Или, полностью ли загружено содержимое файла CSS, затем полностью оценивается, а затем сразу применяется к HTML? Или что-то еще?
Загружает все CSS, затем начинает рисовать документ сверху вниз.
Тестирование в Firefox 5, я ожидал сначала увидеть зеленый цвет, а затем перейти к красному. Этого не произошло. Я попытался с двумя отдельными таблицами стилей с противоречивыми правилами и получил те же результаты.
Это связано с тем, что сначала загружается CSS, а затем, когда он сталкивается с вашим элементом, он применяет только красный стиль из-за того, как работает каскад.
После многих комбинаций единственным способом, с помощью которого я смог работать, был встроенный блок <style>
в <head>
, с конфликтующими правилами, исходящими от <link>
в <body>
Пока я не могу точно сказать, почему это произошло, я полагаю, что браузер не искал CSS в теге тела, начал рисовать, столкнулся с телом CSS, а затем перекрасил.
Являются ли repaints каким-либо образом затронуты CSS?
Честно говоря, я буду больше беспокоиться о том, что JS вызвала переиздание. Но если у вас очень большой DOM, имеет смысл структурировать ваш CSS таким образом, чтобы вы не вызывали переполнения из-за нечетного позиционирования. @Matt дал вам хорошие ссылки, посвященные этой проблеме
Некоторые хорошие ресурсы:
http://www.dayofjs.com/videos/22158462/web-browsers_alex-russel
Алекс Рассел подробно рассказывает около 36 минут о том, как webkit анализирует CSS, как перерабатывает и рецензирует работу, и что запускает их.
http://code.google.com/speed/page-speed/docs/rendering.html
Это основная статья о том, как оптимизировать рендеринг CSS
Ответ 3
Я не уверен в заметном ответе. Я сомневаюсь в правильности.
В соответствии с этой ссылкой от Google Developers браузер сначала загружает HTML файл, и когда он видит файл CSS, связанный с внешним ресурсом, он начинает загрузку файла CSS в то время как он одновременно создает структуру DOM для данного HTML файла, поскольку CSS не повлияет на DOM. Обратите внимание, что он не применяет никаких стилей к документу, когда браузер загружает файл CSS.
После загрузки файла CSS (предположим, что нет файлов script), и если построение DOM завершено, браузер начинает сопоставлять свойства CSS с этими узлами в дереве DOM. После этого создается другое дерево под названием Render tree, которое строит все объекты, которые должны отображаться, в виде прямоугольников. Только после завершения рендеринга дерево начинает рисоваться на экране.
Подводя итог:
- браузер полностью загружает файл CSS.
- Браузер не применяет никаких стилей к странице при ее загрузке. Только после завершения загрузки он начинает отображать правила.
- Правила применяются только на этапе построения дерева рендеринга.
- Загрузка файла CSS не блокирует загрузку HTML. Вы должны заметить, что браузер
Сначала загружаются все html файлы, а затем загружаются файлы стиля и script.
Вы можете использовать консоль разработчика Chrome, чтобы проверить их. Используйте вкладку временной шкалы, чтобы увидеть все это.
Образец изображения временной шкалы отображается здесь. Ссылка, опубликованная в начале этого ответа, объясняет все.