> Как парсится и обрабатывается JavaScript в браузере (JavaScript)
Уровень: senior · Роль: frontend · Категория: Технические вопросы
Компании: 1221 Systems
Стек: JavaScript
> Пример ответа
Короткий ответ
Браузер парсит JavaScript в два этапа: сначала загружает и парсит HTML, затем при встрече тега <script> (без async/defer) блокирует парсинг DOM, загружает скрипт, парсит его в AST, компилирует в байткод через V8/SpiderMonkey и выполняет. После выполнения парсинг HTML возобновляется. Async и defer меняют поведение: defer сохраняет порядок и ждёт DOM, async выполняется сразу после загрузки. Event loop управляет очередью задач.
Подробное объяснение
Процесс начинается с парсинга HTML в DOM-дерево. Когда парсер встречает тег <script> без атрибутов async или defer, он немедленно останавливает построение DOM, загружает скрипт (если внешний), затем парсит его в абстрактное синтаксическое дерево (AST). Современные движки (V8, JavaScriptCore) компилируют AST в байткод через JIT-компилятор, который может оптимизировать горячие участки кода во время выполнения.
После компиляции скрипт выполняется в главном потоке, блокируя рендеринг и парсинг HTML. Это критично для производительности: долгий скрипт задерживает отрисовку страницы. После выполнения парсинг HTML продолжается с места остановки.
Атрибуты async и defer меняют поведение:
defer: скрипт загружается параллельно с парсингом HTML, но выполняется только после полного построения DOM, в порядке объявления.async: скрипт загружается параллельно и выполняется сразу после загрузки, блокируя парсинг HTML на время выполнения, порядок не гарантируется.
Event loop управляет выполнением: синхронный код выполняется в стеке вызовов, асинхронные задачи (setTimeout, fetch, обработчики событий) попадают в очередь макрозадач или микрозадач (Promise, MutationObserver). Микрозадачи выполняются после каждой макрозадачи до начала следующего рендеринга.
На практике
Для оптимизации загрузки:
- Размещайте скрипты в конце
<body>или используйтеdeferдля скриптов, которые зависят от DOM. asyncподходит для независимых скриптов (аналитика, реклама), где порядок не важен.- Критический JavaScript (для первого экрана) можно инлайнить в
<head>для мгновенного выполнения. - Используйте
type="module"для ES-модулей - они по умолчанию ведут себя какdefer. - Избегайте синхронных
XMLHttpRequestи долгих циклов в главном потоке.
Пример кода
HTML<!-- Блокирующий скрипт: парсинг HTML остановится до загрузки и выполнения --><script src="heavy.js"></script><!-- Defer: загружается параллельно, выполняется после DOM --><script defer src="app.js"></script><!-- Async: загружается параллельно, выполняется сразу после загрузки --><script async src="analytics.js"></script><!-- ES-модуль: автоматически defer --><script type="module" src="module.js"></script>
Как отвечать на собеседовании
Начни с краткого описания процесса: парсинг HTML, блокировка, компиляция, выполнение. Затем углубись в детали: AST, JIT, event loop, разница между async и defer. Упомяни влияние на Core Web Vitals (LCP, FID). Приведи пример оптимизации: critical CSS + inline JS для первого экрана. Если спросят про модули, объясни разницу с классическими скриптами. Избегай излишней теории про байткод, если не спрашивают конкретно.
Что проверяет интервьюер
- Понимание блокирующего поведения скриптов и влияния на парсинг HTML.
- Знание атрибутов async/defer и их практического применения.
- Осведомлённость о JIT-компиляции и event loop.
- Умение оптимизировать загрузку JavaScript для производительности.
- Понимание работы ES-модулей в браузере.
Типичные ошибки
- Путать async и defer: думать, что async сохраняет порядок выполнения.
- Считать, что скрипты в конце
<body>не блокируют парсинг - они всё равно блокируют, но после полного DOM. - Игнорировать влияние на рендеринг: долгий синхронный код задерживает отрисовку.
- Не учитывать, что
type="module"ведёт себя как defer, а не async. - Думать, что event loop - это часть спецификации JavaScript, а не окружения (браузера/Node.js).
> Похожие задачи по frontend
Как реализовать функцию memo для кеширования результатов вызовов по аргументам в JavaScript
В чем разница между document.getElementsByClassName и querySelectorAll в JavaScript
Что такое Zustand и как он используется
Что такое гидрация в веб-разработке
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью