Останавливает ли браузер все сетевые запросы при получении тега script
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Влияние тега script на сетевые запросы в браузере
Да, браузер останавливает все параллельные сетевые запросы при получении тега <script> без атрибутов async или defer, если этот скрипт расположен в теле страницы (body) и не является модулем. Это поведение связано с классической моделью блокирующего (синхронного) выполнения JavaScript в HTML.
Почему происходит остановка запросов?
Браузеры исторически используют синхронный парсинг и исполнение HTML. Когда парсер встречает тег <script>, он должен выполнить его немедленно, потому что скрипт потенциально может:
- Изменять DOM (
document.write) - Обращаться к незагруженным ресурсам
- Влиять на дальнейший парсинг страницы
Чтобы гарантировать корректное состояние DOM и избежать конфликтов, браузер:
- Приостанавливает парсинг HTML
- Блокирует загрузку других ресурсов (картинки, стили, скрипты)
- Выполняет скрипт (загружает его если нужно, затем исполняет)
- Возобновляет парсинг только после завершения исполнения
Это поведение описано в спецификации HTML и реализовано для обеспечения консистентности DOM.
Пример блокирующего скрипта
<!-- Этот скрипт остановит все запросы до своего выполнения -->
<body>
<img src="large-image.jpg"> <!-- Загрузка будет приостановлена -->
<script src="critical-script.js"></script> <!-- Блокирующий скрипт -->
<div>Другие элементы</div> <!-- Парсинг остановится здесь -->
</body>
Как избежать блокировки запросов?
Современные подходы позволяют избежать этой блокировки:
Атрибут async
<script async src="script.js"></script>
- Скрипт загружается параллельно с парсингом HTML
- Выполняется немедленно после загрузки, потенциально прерывая парсинг
- Не блокирует загрузку других ресурсов во время своей загрузки
Атрибут defer
<script defer src="script.js"></script>
- Скрипт загружается параллельно с парсингом HTML
- Выполняется после завершения парсинга всей страницы
- Полностью не блокирует загрузку ресурсов и парсинг
Модули ES6
<script type="module" src="module.js"></script>
- По умолчанию имеют поведение defer
- Загружаются и выполняются без блокировки парсинга
Что происходит с уже отправленными запросами?
Важно понимать разницу:
- Новые запросы не запускаются во время блокировки
- Уже отправленные запросы обычно не прерываются — они продолжают загрузку, но браузер может не обрабатывать ответы до завершения скрипта
- Обработка ответов может быть задержана, так что фактическая загрузка ресурсов замедляется
Практические следствия для оптимизации
Для современной фронтенд-разработки рекомендуется:
- Использовать
async/deferдля всех скриптов, не критичных для отображения страницы - Критические скрипты помещать в начало документа, но минимизировать их размер
- Внедрять предзагрузку через
<link rel="preload">для важных ресурсов - Разделять скрипты на модули для лучшего контроля над выполнением
- Измерять влияние через Performance API и инструменты разработчика
// Можно отследить блокировку через Performance Timeline
performance.getEntriesByType('resource').forEach(entry => {
console.log(`${entry.name}: ${entry.duration}ms`);
});
Вывод
Браузер действительно останавливает инициацию новых сетевых запросов при встрече блокирующего тега <script>, но уже запущенные запросы продолжают выполняться. Это поведение — ключевой фактор для оптимизации скорости загрузки страниц. Использование async, defer и модулей ES6 позволяет полностью избежать этой блокировки и обеспечивает параллельную загрузку ресурсов, что критически важно для современных веб-приложений.