Как работает inline скрипт в HTML: сначала выполняется скрипт или продолжается парсинг HTML
Что проверяют
Знаете ли вы, как HTML-парсер взаимодействует с JavaScript и почему скрипт в неудачном месте задерживает первую отрисовку. Следом обычно спрашивают про async и defer и работают ли они для inline-скрипта.
Как отвечать
Короткий ответ: обычный inline <script> без атрибутов останавливает парсинг. Парсер доходит до тега, отдаёт код движку, ждёт завершения и только потом продолжает строить DOM. Причина историческая: скрипт может вызвать document.write и вставить разметку прямо в поток, поэтому парсер не вправе идти дальше.
Дальше раскройте детали:
- доступный DOM: скрипт видит только то, что разобрано выше него. Элемент, объявленный ниже, через
document.querySelectorне найдётся; - стили: если выше подключена ещё не загруженная таблица стилей, inline-скрипт ждёт её, потому что может читать вычисленные стили. Так CSS косвенно блокирует и парсинг;
- внешний классический скрипт: тоже блокирует парсер, уже на время загрузки и выполнения. Preload scanner при этом заранее находит ресурсы ниже и начинает их качать;
defer: загрузка параллельно с парсингом, выполнение после разбора документа передDOMContentLoaded, порядок сохраняется;async: выполнение сразу по готовности файла, в любом порядке;type="module": модули отложены по умолчанию, как сdefer, а inline-модулю можно датьasync.
Главная ловушка: у классического inline-скрипта атрибуты async и defer игнорируются, они работают только вместе с src. Чтобы inline-код не мешал, его делают коротким, ставят в конец <body> или оборачивают в обработчик DOMContentLoaded.
Где спотыкаются
Считают, что inline-скрипт выполняется параллельно с парсингом, раз его не нужно скачивать. Скачивать не нужно, а останавливать парсер он всё равно будет.
Ставят defer на inline-скрипт и уверены, что он отложен. Браузер молча выполнит его сразу.
Забывают про связку CSS и JS: тяжёлый <link rel="stylesheet"> над inline-скриптом задерживает не только отрисовку, но и выполнение скрипта, и разбор всего, что ниже.