Использование async и defer для управления скриптами
Опубликовано:
В мире веб-разработки оптимизация времени загрузки страниц имеет решающее значение. Два мощных атрибута тега
<script> — async и defer — могут существенно повлиять на производительность сайта. Использование этих атрибутов без их глубокого понимания может негативно сказаться на производительности и привести к ошибкам. Давайте начнём с основ и узнаем, что делают эти атрибуты и когда их следует использовать.Основы: как загружаются скрипты
По умолчанию, когда браузер встречает тег <script>, он:
- Приостанавливает парсинг HTML
- Загружает скрипт
- Выполняет скрипт
- Возобновляет парсинг HTML
Этот процесс может замедлить рендеринг страницы, особенно если речь идёт о больших скриптах или медленных соединениях. Кроме того, это может привести к ошибкам, если скрипт запускается до полной загрузки определённых элементов HTML, что случается, если скрипт неправильно размещён в документе.
async и defer: Обоюдоострый меч
async
<script async src="script.js"></script>- Что делает: Загружает скрипт асинхронно, пока продолжается парсинг HTML.
- Когда выполняется: Сразу после загрузки, приостанавливая парсинг HTML.
- Где используется: Независимые скрипты, не зависящие от других скриптов или содержимого DOM.
- Предостережение: Может выполняться не по порядку, потенциально нарушая зависимости.
defer
<script defer src="script.js"></script>- Что делает: Загружает скрипт, пока продолжается парсинг HTML.
- Когда выполняется: После завершения парсинга HTML, но до события DOMContentLoaded.
- Где используется: Скрипты, зависящие от содержимого DOM или требующие выполнения в определённом порядке.
- Предостережение: Может отложить выполнение критической функциональности.
Сравнение поведения
| Атрибут | Загрузка | Выполнение | Парсинг HTML | Основной риск |
|---|---|---|---|---|
| Отсутствует | Блокирующая | Немедленное | Останавливается | Медленный начальный рендер |
| async | Параллельная | Как можно скорее | Останавливается, затем продолжается | Состояние гонки |
| defer | Параллельная | После HTML | Продолжается | Отложенная функциональность |
Порядок выполнения: async, defer и оба
Понимание порядка выполнения скриптов с различными атрибутами важно для управления зависимостями и обеспечения надлежащей функциональности. Вот как это работает:
- Обычные (без
asyncилиdefer):- Выполняются в том порядке, в котором они встречаются в документе.
- Блокируют парсинг HTML до тех пор, пока не будут загружены и выполнены.
- Скрипты с
async:- Загружаются параллельно и выполняются, как только становятся доступными.
- Порядок выполнения не гарантируется; запускаются сразу после загрузки.
- Могут выполняться до полной загрузки DOM.
- Скрипты с
defer:- Загружаются параллельно, но выполняются только после завершения парсинга HTML.
- Выполняются в том порядке, в котором встречаются в документе.
- Выполняются до события
DOMContentLoaded.
- Скрипты с
asyncиdefer:- Атрибут
asyncимеет приоритет в современных браузерах. - В старых браузерах, не поддерживающих
async, они возвращаются к поведениюdefer.
- Атрибут
Пример порядка выполнения
<script src="1.js"></script>
<script async src="2.js"></script>
<script async src="3.js"></script>
<script defer src="4.js"></script>
<script defer src="5.js"></script>Возможный порядок выполнения:
1.js(блокирует парсинг)2.jsили3.js(в зависимости от того, что загрузится первым)3.jsили2.js(в зависимости от того, что загрузится вторым)4.js5.js
Лучшие практики
- Используйте
asyncдля независимых скриптов, таких как аналитика. - Используйте
deferдля скриптов, зависящих от DOM или других скриптов. - Размещайте скрипты в
<head>сasyncилиdefer, чтобы начать загрузку раньше. - Для критически важных скриптов используйте инлайн-скрипты в
<head>.
Поддержка браузерами
И async, и defer широко поддерживаются в современных браузерах. Для старых браузеров следует использовать загрузчик скриптов или помещать скрипты в конец <body>.