Атрибут defer
Атрибут defer откладывает выполнение скрипта до тех пор, пока вся страница не будет загружена полностью.
Синтаксис
Значения
Значение по умолчанию
По умолчанию этот атрибут выключен.
HTML5 IE Cr Op Sa Fx
Тег SCRIPT, атрибут defer Введите ваш возраст
В скрипте данного примера значение текстового поля с именем textField приравнивается 17. Однако при запуске скрипта форма еще не инициализирована, поэтому требуется использовать атрибут defer . Без него будет выведена ошибка.
Браузеры
В Firefox 3.6 и старше атрибут defer игнорируется, если у тега не указан атрибут src . В Firefox 3.5 поведение другое и defer работает даже для встроенных скриптов.
Не выкладывайте свой код напрямую в комментариях, он отображается некорректно. Воспользуйтесь сервисом cssdeck.com или jsfiddle.net, сохраните код и в комментариях дайте на него ссылку. Так и результат сразу увидят.
Типы тегов

HTML5

Блочные элементы

Строчные элементы

Универсальные элементы

Нестандартные теги

Осуждаемые теги

Видео

Документ

Звук

Изображения

Объекты

Скрипты

Списки

Ссылки

Таблицы

Текст

Форматирование

Формы

Фреймы
Скрипты — атрибуты async и defer
Когда браузер загружает HTML и доходит до тега … , он не может продолжать строить DOM. Он должен сначала выполнить скрипт. То же самое происходит и с внешними скриптами — браузер должен подождать, пока загрузится скрипт, выполнить его, и только затем обработать остальную страницу.
Это ведёт к двум важным проблемам:
- Скрипты не видят DOM-элементы ниже себя, поэтому к ним нельзя добавить обработчики и т.д.
- Если вверху страницы объёмный скрипт, он «блокирует» страницу на время загрузки и выполнения.
Конечно, есть пути, как это обойти. Например, мы можем поместить скрипт внизу страницы. Тогда он сможет видеть элементы над ним и не будет препятствовать отображению содержимого страницы.
Но это решение далеко от идеального. Например, браузер замечает скрипт (и может начать загружать его) только после того, как он полностью загрузил HTML-документ. В случае с длинными HTML-страницами это может создать заметную задержку.
К счастью, есть два атрибута тега , которые решают нашу проблему — defer и async .
defer
Атрибут defer сообщает браузеру, что он должен продолжать обрабатывать страницу и загружать скрипт в фоновом режиме, а затем запустить этот скрипт, когда DOM дерево будет полностью построено. Важный момент — скрипт с атрибутом defer всегда выполняются, когда дерево DOM готово, но до события DOMContentLoaded .
Отложенные с помощью defer скрипты сохраняют порядок относительно друг друга, как и обычные скрипты. Поэтому, если сначала в html-коде идет большой скрипт, а затем маленький — то последний будет ждать окончания загрузки и выполнения первого. Спецификация требует последовательного выполнения скриптов согласно порядку в документе.
defer src="large.js"> defer src="small.js">
async
Атрибут async означает, что скрипт абсолютно независим:
- Содержимое страницы отображается сразу же — async его не блокирует.
- DOMContentLoaded может произойти как до, так и после async , никаких гарантий нет.
- Асинхронные скрипты не ждут друг друга. Меньший скрипт small.js идёт вторым, но скорее всего загрузится раньше large.js , поэтому и запустится первым. То есть, скрипты выполняются в порядке загрузки.
Асинхронные скрипты очень полезны для добавления на страницу сторонних скриптов — счётчиков, рекламы и т.д. Они не зависят от наших скриптов, и мы тоже не должны ждать их.
async src="https://google-analytics.com/analytics.js">
Динамически загружаемые скрипты
Мы можем также добавить скрипт и динамически, с помощью js-кода:
let script = document.createElement('script'); script.src = 'large.js'; document.body.append(script);
Динамически загружаемый скрипт по умолчанию ведет себя как «async» — начинает загружаться, как только он будет добавлен в документ:
- Сам скрипт никого не ждет, и его никто не ждёт
- Если первым загрузился — первым и запустился
Мы можем изменить относительный порядок скриптов с «первый загрузился — первый выполнился» на порядок, в котором они идут в документе (как в обычных скриптах) с помощью явной установки свойства async в false .
function loadScript(src) let script = document.createElement('script'); script.src = src; script.async = false; document.body.append(script); > // large.js запускается первым, так как async=false loadScript('large.js'); loadScript('small.js');
- DOM, часть 4 из 4. Атрибуты и свойства
- DOM, часть 3 из 3. Поиск элементов
- DOM, часть 2 из 3. Изменение документа
- DOM, часть 1 из 3. Навигация по элементам
- React и Redux вместе. Часть 7 из 7
- React и Redux вместе. Часть 6 из 7
- React и Redux вместе. Часть 5 из 7
Каталог оборудования
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Производители
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Функциональные группы
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Категории блога
Облако тегов
- 1С:Предприятие (31)
- API (29)
- Bash (43)
- CLI (124)
- CMS (139)
- CSS (50)
- Frontend (75)
- HTML (66)
- JavaScript (150)
- Laravel (72)
- Linux (171)
- MySQL (76)
- PHP (125)
- React.js (66)
- SSH (27)
- Ubuntu (69)
- Web-разработка (509)
- WordPress (73)
- Yii2 (69)
- БазаДанных (95)
- Битрикс (66)
- Блог (29)
- Верстка (43)
- ИнтернетМагаз… (84)
- КаталогТоваров (87)
- Класс (30)
- Клиент (28)
- Ключ (28)
- Команда (88)
- Компонент (60)
- Конфигурация (66)
- Корзина (32)
- ЛокальнаяСеть (32)
- Модуль (34)
- Навигация (31)
- Настройка (143)
- ПанельУправле… (29)
- Плагин (33)
- Пользователь (26)
- Практика (101)
- Сервер (77)
- Событие (28)
- Теория (106)
- Установка (67)
- Файл (51)
- Форма (58)
- Фреймворк (192)
- Функция (36)
- ШаблонСайта (68)
Скрипты: async, defer
В современных сайтах скрипты обычно «тяжелее», чем HTML: они весят больше, дольше обрабатываются.
Когда браузер загружает HTML и доходит до тега , он не может продолжать строить DOM. Он должен сначала выполнить скрипт. То же самое происходит и с внешними скриптами : браузер должен подождать, пока загрузится скрипт, выполнить его, и только затем обработать остальную страницу.
Это ведёт к двум важным проблемам:
- Скрипты не видят DOM-элементы ниже себя, поэтому к ним нельзя добавить обработчики и т.д.
- Если вверху страницы объёмный скрипт, он «блокирует» страницу. Пользователи не видят содержимое страницы, пока он не загрузится и не запустится:
. содержимое перед скриптом.
. содержимое после скрипта.
Конечно, есть пути, как это обойти. Например, мы можем поместить скрипт внизу страницы. Тогда он сможет видеть элементы над ним и не будет препятствовать отображению содержимого страницы:
. всё содержимое над скриптом.
Но это решение далеко от идеального. Например, браузер замечает скрипт (и может начать загружать его) только после того, как он полностью загрузил HTML-документ. В случае с длинными HTML-страницами это может создать заметную задержку.
Такие вещи незаметны людям, у кого очень быстрое соединение, но много кто в мире имеет медленное подключение к интернету или использует не такой хороший мобильный интернет.
К счастью, есть два атрибута тега , которые решают нашу проблему: defer и async .
defer
Атрибут defer сообщает браузеру, что он должен продолжать обрабатывать страницу и загружать скрипт в фоновом режиме, а затем запустить этот скрипт, когда DOM дерево будет полностью построено.
Вот тот же пример, что и выше, но с defer :
. содержимое перед скриптом.
. содержимое после скрипта.
- Скрипты с defer никогда не блокируют страницу.
- Скрипты с defer всегда выполняются, когда дерево DOM готово, но до события DOMContentLoaded .
Следующий пример это показывает:
. содержимое до скрипта.
// (2) . содержимое после скрипта.
- Содержимое страницы отобразится мгновенно.
- Событие DOMContentLoaded подождёт отложенный скрипт. Оно будет сгенерировано, только когда скрипт (2) будет загружен и выполнен.
Отложенные с помощью defer скрипты сохраняют порядок относительно друг друга, как и обычные скрипты.
Допустим, у нас есть два скрипта c defer : small.js и long.js :
Браузеры сканируют страницу на предмет скриптов и загружают их параллельно в целях увеличения производительности. Поэтому и в примере выше оба скрипта скачиваются параллельно. small.js скорее всего загрузится первым.
…Но defer не только говорит браузеру «не блокировать рендеринг», он также обеспечивает правильную последовательность выполнения скриптов. Даже если small.js загрузится первым, он будет ждать выполнения long.js .
Это важно в тех случаях, когда нам сначала нужно загрузить JavaScript-библиотеку, а затем скрипт, который от неё зависит.
Атрибут defer предназначен только для внешних скриптов
Атрибут defer будет проигнорирован, если в теге нет src .
async
Атрибут async означает, что скрипт абсолютно независим:
- Страница не ждёт асинхронных скриптов, содержимое обрабатывается и отображается.
- Событие DOMContentLoaded и асинхронные скрипты не ждут друг друга:
- DOMContentLoaded может произойти как до асинхронного скрипта (если асинхронный скрипт завершит загрузку после того, как страница будет готова),
- …так и после асинхронного скрипта (если он короткий или уже содержится в HTTP-кеше)
Так что если у нас есть несколько скриптов с async , они могут выполняться в любом порядке. То, что первое загрузится – запустится в первую очередь:
. содержимое перед скриптами.
. содержимое после скриптов.
- Содержимое страницы отображается сразу же : async его не блокирует.
- DOMContentLoaded может произойти как до, так и после async , никаких гарантий нет.
- Асинхронные скрипты не ждут друг друга. Меньший скрипт small.js идёт вторым, но скорее всего загрузится раньше long.js , поэтому и запустится первым. То есть, скрипты выполняются в порядке загрузки.
Асинхронные скрипты очень полезны для добавления на страницу сторонних скриптов: счётчиков, рекламы и т.д. Они не зависят от наших скриптов, и мы тоже не должны ждать их:
Атрибут async предназначен только для внешних скриптов
Как и в случае с defer , атрибут async будет проигнорирован, если в теге нет src .
Динамически загружаемые скрипты
Мы можем также добавить скрипт и динамически, с помощью JavaScript:
let script = document.createElement('script'); script.src = "/article/script-async-defer/long.js"; document.body.append(script); // (*)Скрипт начнёт загружаться, как только он будет добавлен в документ (*) .
Динамически загружаемые скрипты по умолчанию ведут себя как «async».
- Они никого не ждут, и их никто не ждёт.
- Скрипт, который загружается первым – запускается первым (в порядке загрузки).
Мы можем изменить относительный порядок скриптов с «первый загрузился – первый выполнился» на порядок, в котором они идут в документе (как в обычных скриптах) с помощью явной установки свойства async в false :
let script = document.createElement('script'); script.src = "/article/script-async-defer/long.js"; script.async = false; document.body.append(script);Например, здесь мы добавляем два скрипта. Без script.async=false они запускались бы в порядке загрузки ( small.js скорее всего запустился бы раньше). Но с этим флагом порядок будет как в документе:
function loadScript(src) < let script = document.createElement('script'); script.src = src; script.async = false; document.body.append(script); >// long.js запускается первым, так как async=false loadScript("/article/script-async-defer/long.js"); loadScript("/article/script-async-defer/small.js");Итого
У async и defer есть кое-что общее: они не блокируют отрисовку страницы. Так что пользователь может просмотреть содержимое страницы и ознакомиться с ней сразу же.
Но есть и значимые различия:
Порядок DOMContentLoaded async Порядок загрузки (кто загрузится первым, тот и сработает). Не имеет значения. Может загрузиться и выполниться до того, как страница полностью загрузится. Такое случается, если скрипты маленькие или хранятся в кеше, а документ достаточно большой. defer Порядок документа (как расположены в документе). Выполняется после того, как документ загружен и обработан (ждёт), непосредственно перед DOMContentLoaded . Страница без скриптов должна быть рабочей
Пожалуйста, помните, что когда вы используете defer , страница видна до того, как скрипт загрузится.
Пользователь может знакомиться с содержимым страницы, читать её, но графические компоненты пока отключены.
Поэтому обязательно должна быть индикация загрузки, нерабочие кнопки – отключены с помощью CSS или другим образом. Чтобы пользователь явно видел, что уже готово, а что пока нет.
На практике defer используется для скриптов, которым требуется доступ ко всему DOM и/или важен их относительный порядок выполнения.
А async хорош для независимых скриптов, например счётчиков и рекламы, относительный порядок выполнения которых не играет роли.
Атрибуты defer и async
С помощью этих атрибутов можно сказать браузеру как и в каком порядке загружать скрипты.
Время чтения: меньше 5 мин
Открыть/закрыть навигацию по статье
Обновлено 6 октября 2022
Кратко
Скопировать ссылку «Кратко» Скопировано
Скрипты с атрибутами defer загружаются и выполняются последовательно, а с async – асинхронно. Кроме того, defer всегда ждёт, пока весь HTML-документ будет готов, а async выполняется сразу после загрузки.
Как пишется
Скопировать ссылку «Как пишется» Скопировано
Оба атрибута являются логическими. Это значит, что им не нужно задавать значение. Если атрибут указан, то браузер понимает это как команду к действию. Чтобы отменить эффект, достаточно убрать атрибут.
Как понять
Скопировать ссылку «Как понять» Скопировано
Атрибут async
Скопировать ссылку «Атрибут async» Скопировано
Указывает браузеру по возможности загружать скрипт асинхронно.
Скрипт выполняется полностью асинхронно. Это означает, что файл будет выполняться без ожидания загрузки и отображения веб-страницы. При обнаружении браузер не останавливает обработку страницы, а спокойно работает дальше. Когда скрипт будет загружен – он выполнится.
script src="script1.js" async> script> script src="script2.js" async> script>Первым выполнится тот скрипт, который быстрее загрузится.
Поддерживается всеми браузерами, кроме IE9-.
Атрибут defer
Скопировать ссылку «Атрибут defer» Скопировано
Указывает браузеру что скрипт должен выполняться после разбора документа, но до события DOM Content Loaded .
Скрипты с атрибутом defer будут предотвращать запуск события DOM Content Loaded до тех пор, пока скрипт не загрузится полностью и не завершится его инициализация.
script src="script1.js" defer> script> script src="script2.js" defer> script>Первым всегда выполнится script1 . js , который подключён раньше. Даже если script2 . js загрузится раньше, он будет выполнен после первого скрипта.
Применение
Скопировать ссылку «Применение» Скопировано
На практике defer используется для скриптов, которым требуется доступ ко всему DOM-дереву или если важен их порядок выполнения.
А async хорош для независимых скриптов, например счётчиков и рекламы, порядок выполнения которых не играет роли.
Подсказки
Скопировать ссылку «Подсказки» Скопировано
Динамически вставленный (например, вставленный при помощи document . create Element ) по умолчанию загружается браузером асинхронно.
На собеседовании
Скопировать ссылку «На собеседовании» Скопировано
Скопировать ссылку «Объясните разницу между script, script async и script defer.» Скопировано
Это вопрос без ответа. Вы можете помочь! Почитайте о том, как контрибьютить в Доку.