Ответ
Браузер продолжает парсинг HTML при:
- Загрузке скриптов с атрибутами
asyncилиdefer - Картинках, стилях, iframe, видео (но они могут блокировать рендеринг)
- Скриптах, добавленных динамически через
document.createElement('script')
Пример:
<script async src="script.js"></script> <!-- Не блокирует парсинг -->
<script defer src="script.js"></script> <!-- Выполнится после парсинга -->
<img src="image.jpg"> <!-- Не блокирует парсинг, но может задержать рендеринг -->
Обычные скрипты без атрибутов (<script src="...">) блокируют и парсинг, и рендеринг.
Ответ 18+ 🔞
Ага, слушай, вот тебе наглядная картина, как этот ваш браузер, сука, работает. Представь, он там, этот HTML, разбирает, как голодный студент лапшу доширак — вроде и торопится, но иногда натыкается на такие моменты, что хоть стой, хоть падай.
Так вот, есть у него, у браузера, правило простое, как три копейки: обычный скрипт без всяких там прибамбасов — это полный пиздец и стоп-кран. Увидел <script src="..."> — всё, приехали. Бросает он парсинг, бежит скрипт качать и выполнять, и только потом, когда тот отыграл, продолжает HTML жевать. И рендеринг, соответственно, тоже ждёт, как дурак у закрытой двери.
Но! Не всё так печально, есть же и свет в конце тоннеля, блядь. Вот когда ты скрипту эти волшебные атрибуты пропишешь — async или defer — ну совсем другая история, ёпта!
async— это как: «О, скрипт! Ладно, качаюсь я параллельно, не мешай, парсинг продолжаю. Но как только скачался — всё, парсинг нахуй, я сначала выполнюсь!». Порядок выполнения — как повезёт, кто первый загрузился, тот и в дамки.defer— это интеллигентнее: «Качаюсь я тихонько, парсинг не трогаю. И выполнюсь я чинно и благородно только тогда, когда весь HTML будет разобран до конца». Порядок скриптов сохраняется.
И ещё, блядь, картинки, стили, iframe — они парсинг вроде не блокируют, браузер их в фоне тянет. Но! Рендеринг они могут задержать конкретно, потому что браузер, мудя, думает: «А хули рисовать-то, если стили ещё не пришли?» или «Место под картинку надо reserved, сука, оставить».
Ну и динамически добавленные скрипты — те, что через createElement воткнули — они по умолчанию ведут себя как async. Хитро, да?
Смотри, вот тебе пример, чтобы в башке уложилось:
<script async src="script.js"></script> <!-- Не блокирует парсинг, выполнится когда загрузится -->
<script defer src="script.js"></script> <!-- Не блокирует парсинг, выполнится в конце -->
<img src="image.jpg"> <!-- Парсинг не блокирует, но рендеринг может встать колом, пока не поймёт размеры, ядрёна вошь -->
А теперь запомни раз и навсегда: обычный скрипт без атрибутов — это зло в квадрате. Он и парсинг, и рендеринг блокирует напрочь. Всё ждёт, пока этот файл, блядь, скачается и отработает. Вот такие пироги с котятами.