Зачем использовать отсрочку с Google Maps Javascript?

JavaScript Maps выполняет некоторые сложные манипуляции с DOM. Тем не менее, хорошие документы предлагают загружать его с флагом defer:

<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap" async defer></script>

Зачем предлагать флаг defer для скрипта, выполняющего манипуляции с DOM? Я прошу узнать как о флаге defer, так и об API Карт Google, так как, похоже, я неправильно понимаю, что делает один из них.


person dotancohen    schedule 28.04.2016    source источник


Ответы (2)


Обычно тег 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?

Две причины:

  1. Это позволяет продолжить синтаксический анализ, пока скрипт загружается, и
  2. Это означает, что скрипт не запускается до завершения синтаксического анализа.

Если вы не использовали defer и разместили свои теги script неоптимально, использование defer помогает сценарию API вести себя правильно, позволяя браузеру завершить построение DOM до того, как сценарий попытается манипулировать ею.

Многие люди по-прежнему помещают теги script в раздел head документа, хотя обычно это худшее место для их размещения, если только вы не используете defer (или async). В большинстве случаев лучшее место (если у вас нет причин делать что-то еще) находится в самом конце, непосредственно перед закрывающим тегом </body>, так что A) Ваш сайт отображается быстро, не дожидаясь скрипты; и B) DOM полностью построен, прежде чем вы попытаетесь манипулировать им. Рекомендация defer может избавить их от проблем с поддержкой из-за того, что люди помещают свои теги script слишком рано в HTML.

person T.J. Crowder    schedule 28.04.2016
comment
Я думаю, что я вижу. Таким образом, кажется, что статья, которую я прочитал, чтобы понять отложенный и асинхронный атрибуты совершенно неверны и даже противоречат спецификации. Позор, что он занимает столь высокое место в Google. - person dotancohen; 28.04.2016
comment
@dotancohen: Нет, это правильно, просто немного расплывчато, когда говорится ... не содержит никакой гадости document.write или модификации DOM:. Что он должен сказать, так это что-то вроде ... не содержит каких-либо изменений document.write или DOM, предназначенных для запуска в парсере. (поскольку есть и другие вещи, которые вы можете сделать, а не только document.write, который будет полагаться на то, что синтаксический анализатор задержится в ожидании запуска вашего скрипта). Это не должно было создавать впечатление, что все изменения DOM исключены. - person T.J. Crowder; 28.04.2016

В примерах карт Google используются флаги async и defer.

  • Флаг async позволяет скрипту загружаться параллельно с анализом DOM и выполняться, как только API будет готов.
  • Флаг defer позволяет скрипту загружаться параллельно с разбором DOM, но гарантирует, что скрипт не будет выполняться до тех пор, пока не завершится синтаксический анализ DOM.

async поддерживается современными браузерами HTML5, а defer универсальна. Когда теги используются вместе, defer является просто запасным вариантом для старых браузеров и будет игнорироваться, если async поддерживается.

В этих простых примерах подойдет либо async, либо defer, хотя ни то, ни другое не обязательно. В данном случае это только для производительности.

Ссылки:
Ускорьте Google Maps (и все остальное) с помощью async & defer
асинхронные и отсроченные атрибуты: рост вместе с Интернетом

person Yarin    schedule 20.07.2017