Оказывается, CSS и JS блокируют синтаксический анализ и рендеринг DOM следующим образом.

JavaScript CSS

привет~ Здравствуйте, уважаемые наблюдатели и господа. Я думаю, все слышали это, постарайтесь изо всех сил, чтобыCSSположить голову,JSПоместите его внизу, что может повысить производительность страницы. Однако почему? Вы рассмотрели это? Давно я это знал, но не знал почему.Конечно, можно было заставить его запомнить, чтобы справиться с оценкой, но в практическом применении это должно быть бардак. Итак, вымойте (ван) сердце (ян), кожу (бу), поверхность (лао) и подведите итоги недавней игры.

В качестве дружеского напоминания, эта статья также основана на Xiaobai.Если вы хотите увидеть заключение напрямую, вы можете потянуть его вниз, чтобы увидеть~


Так как это связано с чтением файла, то обязательно потребуется сервер, все файлы я положу в папкуgithubдавай, дай мне немногоstarЯ буду счастлив! Дайте мне еще на Наггетсотличныйя счастливее~

nodeЕдинственное, что нужно объяснить, это эта функция:

function sleep(time) {
  return new Promise(function(res) {
    setTimeout(() => {
      res()
    }, time);
  })
}

Эм! На самом деле задерживается. еслиCSSилиJSимя файла имеетsleep3000Когда префикс такой, это означает, что файл будет возвращен после задержки в 3000 миллисекунд.

используется нижеHTMLФайл выглядит так:

    <!DOCTYPE html>
    <html lang="en">
    <head>
    	<meta charset="UTF-8">
    	<title>Title</title>
    	<style>
    		div {
    			width: 100px;
    			height: 100px;
    			background: lightgreen;
    		}
    	</style>
    </head>
    <body>
    	<div></div>
    </body>
    </html>

буду вставлять разныеJSа такжеCSS.

при использованииcommon.css, с префиксом или без него, содержимое выглядит следующим образом:

div {
  background: lightblue;
}

Ну, не много слов, приступим к тексту!

CSS

оCSS, это все точно знают<link>Производительность метки на голове будет выше, и меньше людей узнают, если<script>а также<link>При этом в голове<script>Может быть лучше на . Почему это? Давайте взглянемCSSправильноDOMКаково влияние.

CSSне блокируетDOMАнализ

Обращать внимание! Здесь говоритсяDOMРазбор, пример доказательства такой, сначала вставить в шапку<script defer src="/js/logDiv.js"></script>,JSСодержимое файла:

const div = document.querySelector('div');
console.log(div);

deferЯ считаю, что все знакомы с атрибутами.MDNЭто описание используется для информирования браузера о том, что сценарий будет выполнен после завершения синтаксического анализа документа, но до запуска события DOMContentLoaded. Установка этого свойства гарантирует, чтоDOMРаспечатать сразу после разбораdiv.

позже<link rel="stylesheet" href="/css/sleep3000-common.css">вставлятьHTMLВ любом месте файла, откройте браузер, вы можете увидеть, что он сначала распечатываетсяdivэтоDOMУзел примерно через 3 секунды станет светло-голубым.div. Это доказываетCSSне будет блокироватьDOMаналитический, хотяCSSЗагрузка занимает 3с, но во время этого процесса браузер тупо ждать не будетCSSПосле скачивания он будет парситьDOMиз.

Вот краткое описание, в браузере происходит парсингDOMгенерироватьDOM Tree, в сочетании сCSSСгенерированоCSS Tree, окончательный составrender tree, а затем визуализировать страницу. Видно, что в этом процессеCSSсовершенно незатронутыйDOM Tree, так что не нужно блокироватьDOMРазбор. Однако,DOM Treeа такжеCSS Treeбудут объединены вrender tree,ЭтоCSSБудет ли страница блокировать рендеринг?

CSSБлокировка рендеринга страницы

В самом деле, пример только что показал, еслиCSSне блокирует рендеринг блокировки страницы, тоCSSПеред загрузкой файла браузер отображает светло-зеленыйdiv, затем он становится светло-голубым. Эта стратегия браузера на самом деле очень разумна, представьте, что без этой стратегии страница сначала покажет первоначальный вид.CSSПосле загрузки вдруг опять поменялось. Пользовательский опыт ужасен, а рендеринг обходится дорого.

Поэтому, исходя из соображений производительности и взаимодействия с пользователем, браузер попытается уменьшить количество отрисовок.CSSЛогично заблокировать отрисовку страницы.

Однако все всегда странно, посмотрите на этот пример,HTMLСтруктура головы следующая:

<header>
    <link rel="stylesheet" href="/css/sleep3000-common.css">
    <script src="/js/logDiv.js"></script>
</header>

Но подумайте, что с этим будет?

Ответ заключается в том, что браузер будет вращаться по кругу в течение трех секунд, но при этом ничего не будет напечатано, после чего появится голубаяdiv, затем распечатайтеnull. Результат, кажется,CSSНе только блокирует рендеринг страницы, но и блокируетDOMАнализ! Подожди минутку, прежде чем ты собираешься перевернуть стол и разглагольствовать обо мне, подумай о том, что мешаетDOMанализ, это только что было доказаноCSSОн не будет блокироваться, поэтому блокировка парсинга страниц фактическиJS! но очевидноJSКод такой простой и уж точно не будет блокироваться так долго, т.е.JSожидающийCSSскачать, зачем это?

Подумайте хорошенько, на самом деле это имеет смысл делать, если содержимое скрипта получить стиль элемента, ширину и т.д.CSSСвойства элемента управления, которые браузер должен вычислить, т. е. зависит отCSS. Браузер не может понять, что такое содержимое скрипта, и, чтобы избежать приобретения стилей, он должен дождаться загрузки всех предыдущих стилей перед его выполнением.JS. Отсюда ситуация в предыдущем примере.

Поэтому судья понимает, почему<script>а также<link>При этом в голове<script>Может наверху лучше? возможно, потому что если<link>Если содержимое загрузки будет быстрее, это не повлияет, а наоборот,JSПришло время подождать, но это время ожидания совершенно не нужно.

JS

JS, то есть,<script>Ярлыки, я думаю, все с ними знакомы, не только блокировкиDOMРазобрать и визуализировать. Однако на самом деле есть некоторые детали, которые можно изучить, давайте внимательно посмотрим вместе.

JSблокироватьDOMРазобрать

Сначала нам нужен новыйJSимя файлаblok.js, содержание следующее:

const arr = [];
for (let i = 0; i < 10000000; i++) {
  arr.push(i);
  arr.splice(i % 3, i % 7, i % 5);
}
const div = document.querySelector('div');
console.log(div);

На самом деле операция с массивом бессмысленна, просто чтобы сделать этоJSФайл требует больше времени для выполнения. Потом вставляешь этот файл в шапку, и браузер запускается.

В результате подсчитано, что каждый может себе представить, что браузер какое-то время будет кружиться, и в процессе ничего не появится. распечатать послеnull, затем светло-зеленыйdiv. явление достаточно для объясненияJSблокироватьDOMпроанализировано. На самом деле причина тоже очень проста для понимания.Браузер не знает, что такое содержимое скрипта.Если сначала разобрать следующееDOM, если скрипт удалит следующееDOM, браузер зря делает свою работу. Не говоря уже о безумномdocument.write. Если браузер не может предсказать содержимое внутри, он просто остановит все и дождется завершения выполнения скрипта, прежде чем начать работу.

Оптимизация этого на самом деле очень очевидна, и она делится на две категории. еслиJSРазмер файла слишком велик, и вы уверены, что нет необходимости блокироватьDOMПри разборе вы можете добавить по мере необходимостиdeferилиasyncатрибут, в это время процесс загрузки скрипта не будет заблокированDOMФ.

А если время выполнения файла слишком велико, можно было бы так же разделить код, вместо кода, который будет выполняться сразу, можно использовать предыдущую черную технологию:setTimeout(). Конечно, современные браузеры достаточно умны, чтобы «заглянуть» позже.DOMсодержание, например<link>,<script>а также<img>При ожидании метки она поможет нам сначала загрузить ресурсы в нее, а не будет ждать, пока она там пропарсится перед загрузкой.

браузер встречает<script>тег, он вызовет рендеринг страницы

Многим чиновникам эта деталь может быть непонятна, собственно, это и есть объяснение вышеизложенному.JSвыполнение будет ждатьCSSПричина загрузки. Сначала бери пример,HTMLВнутриbodyСтруктура выглядит следующим образом:

<body>
	<div></div>
	<script src="/js/sleep3000-logDiv.js"></script>
	<style>
		div {
			background: lightgrey;
		}
	</style>
	<script src="/js/sleep5000-logDiv.js"></script>
	<link rel="stylesheet" href="/css/common.css">
</body>

Этот пример также является чрезвычайно экстремальным примером, но не мешает ему раскрывать много важной информации. Представьте, что будет страница?

Ответ сначала светло-зеленый, затем светло-серый и, наконец, светло-голубой. Отсюда видно, что каждый раз<script>tab, браузер отобразит страницу один раз. Это основано на той же причине, что браузер не знает содержимого скрипта, поэтому при встрече со скриптом он должен сначала отобразить страницу, чтобы убедиться, что скрипт может получить последнюю версию.DOMинформация об элементе, хотя сценариям может не понадобиться эта информация.

резюме

Подводя итог, делаем следующие выводы:

  • CSSне блокируетDOMразбирает, но блокируетDOMоказывать.
  • JSблокироватьDOMпарсит, но браузер "заглядывает"DOM, предварительно загрузите соответствующие ресурсы.
  • браузер встречает<script>и нетdeferилиasyncатрибута, он вызовет отрисовку страницы, поэтому, если предыдущийCSSКогда ресурс еще не загружен, браузер будет ждать его загрузки перед выполнением скрипта.

Итак, теперь вы понимаете, почему<script>Лучше положить его на дно,<link>Голову лучше ставить, если в голове есть и то и другое<script>а также<link>случае лучше всего<script>помещать<link>Это там?

Спасибо, что прочитали это, я надеюсь, что эта статья будет вам полезна.Если у вас есть другое или лучшее мнение, пожалуйста, дайте мне несколько советов! Спасибо~