Выполнение JavaScript откладывается до тех пор, пока не будет создан CSSOM или нет?

Ответ на этот вопрос был мне ясен с тех пор, как я прочитал / узнал о CSSOM, до сегодняшнего дня. Кажется, я не могу найти первоначальную статью, но на примерах она достаточно ясно объяснила, что выполнение JavaScript откладывается до тех пор, пока CSSOM не будет собран из всех <style> а также <link> теги в <head> (кроме тех, кто не подает заявку, на основании @media запросы).
Или, по крайней мере, так я и сделал в то время, и у меня не было причин сомневаться в этом до сегодняшнего дня.

Это, кажется, подтверждается смелым заявлением в этой главе "Основы и производительность в сети" от Google:

... браузер задерживает выполнение скрипта и построение DOM до тех пор, пока не завершит загрузку и создание CSSOM.

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

<head>
  <script>document.write("<!--");</script>
  <style> body { background-color: red; } </style>
  -->
</head>

Итак, давайте удостоверимся. Давайте заменим <style> с

<link rel="stylesheet" type="text/css" href="test.php" />

... и сделать test.php повесить на несколько секунд:

<?php
sleep(10);
header('Content-Type: text/css');
?>

/* adding styles here would be futile */

Если я прав (и js выполнение откладывается до тех пор, пока не будет создан CSSOM), страница остается пустой в течение 10 секунд, перед сборкой CSSOM и перед выполнением <script> что бы прокомментировать <link /> и позволит странице визуализации.

Если он прав, JS запускается, как он встретил и <link /> Запрос никогда не уходит, потому что это комментарий.

Сюрприз:

  • страница отображается сразу. Он прав!
  • но <link /> запрос уходит, а на вкладке браузера отображается значок загрузки в течение 10 секунд. Я тоже прав! Или я? Я в замешательстве, вот что я...

Кто-нибудь может пролить свет на это? Что здесь происходит?
Это имеет отношение к document.write?
Это связано с загрузкой .php файл вместо .css?


Если это имеет какое-то значение, я тестировал в Chrome, на Ubuntu.

Я прошу дать ссылку на достоверный (ре) источник или предоставить красноречивый пример / тест для подкрепления любого ответа, который вы могли бы рассмотреть.

1 ответ

Решение

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

test.php:

<?php
sleep(5);
header('Content-Type: text/css');
echo 'body {background-color: red;}';

index.html:

<link rel="stylesheet" href="test.php">
<script>console.log('done');</script>

console.log вызов не будет выполнен, пока цвет фона не изменится на красный.

Это приводит к выводу, что создание CSSOM не выполняется один раз для всех таблиц стилей, но это постепенный процесс - когда браузер встречает таблицу стилей, он загружает ее, анализирует и затем перемещается. Также, вероятно, браузер сначала создает список всех ресурсов CSS и добавляет их в очередь загрузки, даже до выполнения каких-либо сценариев. Это объясняет, почему запрос сделан, хотя link Тег комментируется скриптом.

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