Обычно тег script
указывает браузеру прекратить синтаксический анализ HTML, получить скрипт, запустить его и только после этого продолжить синтаксический анализ HTML. Это связано с тем, что код скрипта может использовать document.write
для вывода в поток маркеров HTML.
async
и defer
— это механизмы для сообщения браузеру, что можно продолжать синтаксический анализ HTML параллельно с загрузкой файла сценария и запускать файл сценария позже, а не сразу.
Однако они немного отличаются; эта диаграмма из раздела script
WHAT-WG Версия спецификации HTML полезна для понимания различий:
Полная информация в связанной спецификации выше, но вкратце для «классических» скриптов (к которым вы привыкли, но скрипты модулей скоро появятся!):
- И
async
, и defer
позволяют продолжить синтаксический анализ HTML, не дожидаясь загрузки скрипта.
defer
заставит браузер ждать выполнения скрипта, пока синтаксический анализ не будет завершен.
async
только заставит браузер дождаться завершения загрузки скрипта, что означает, что он может запустить скрипт либо до завершения синтаксического анализа, либо после него, в зависимости от того, когда завершится загрузка (и помните, что он может исходить из кеша).
- Если
async
присутствует и поддерживается браузером, он имеет приоритет над defer
.
async
сценарии можно запускать в любом порядке, независимо от порядка их появления в HTML.
defer
сценарии будут запускаться в том порядке, в котором они появляются в HTML, после завершения синтаксического анализа.
async
и defer
хорошо поддерживаются даже в полусовременных браузерах, но не поддерживаются должным образом в IE9 и более ранних версиях, см. здесь и здесь.
Почему флаг defer
предлагается для скрипта, выполняющего манипуляции с DOM?
Две причины:
- Это позволяет продолжить синтаксический анализ, пока скрипт загружается, и
- Это означает, что скрипт не запускается до завершения синтаксического анализа.
Если вы не использовали defer
и разместили свои теги script
неоптимально, использование defer
помогает сценарию API вести себя правильно, позволяя браузеру завершить построение DOM до того, как сценарий попытается манипулировать ею.
Многие люди по-прежнему помещают теги script
в раздел head
документа, хотя обычно это худшее место для их размещения, если только вы не используете defer
(или async
). В большинстве случаев лучшее место (если у вас нет причин делать что-то еще) находится в самом конце, непосредственно перед закрывающим тегом </body>
, так что A) Ваш сайт отображается быстро, не дожидаясь скрипты; и B) DOM полностью построен, прежде чем вы попытаетесь манипулировать им. Рекомендация defer
может избавить их от проблем с поддержкой из-за того, что люди помещают свои теги script
слишком рано в HTML.
person
T.J. Crowder
schedule
28.04.2016