Подтвердить что ты не робот

Можете ли вы использовать атрибуты async и defer для тега HTML script?

Я хотел бы загрузить следующий JavaScript-код, используя defer и async:

<script defer async src="/js/somescript.js"></script>

Так как defer поддерживается Internet Explorer 5. 5+, как вы можете видеть на CanIUse.com, я бы хотел изящно откатиться на использование defer, если асинхронность недоступна. Async, я думаю, лучше использовать, когда он доступен, но не поддерживается до Internet Explorer 10.

Мой вопрос, поэтому, является ли приведенный выше код действительным HTML? Если нет, то возможно ли создать такую ситуацию, используя JavaScript, чтобы изящно прибегнуть к использованию defer в скрипте, когда async недоступна?

4b9b3361

Ответ 1

Из спецификации: https://www.w3.org/TR/2011/WD-html5-20110525/scripting-1.html#attr-script-async

Атрибут defer может быть указан, даже если указан атрибут async, чтобы устаревшие веб-браузеры, поддерживающие только отсрочку (а не async), переключались на поведение отсрочки вместо режима синхронной блокировки, который используется по умолчанию.

Ответ 2

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

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

https://www.w3.org/TR/2011/WD-html5-20110525/scripting-1.html#attr-script-async

Ответ 3

Да, его действительный HTML и он будет работать, как и ожидалось.

Любой браузер, совместимый с W3C, будет распознавать атрибут async и корректно обрабатывать script, тогда как устаревшие версии IE распознают атрибут defer.

Поскольку оба атрибута являются логическими, вам не нужно назначать какое-либо значение.

Ответ 4

К сожалению, defer игнорируется, когда задан async, и async всегда имеет более высокий приоритет. (По крайней мере, в Chrome. Честно говоря, не тестировал в других браузерах, но думаю, что результат будет таким же.)

И лично я считаю, что очень плохо, что defer игнорируется. Представьте себе ситуацию, когда мы хотели бы, чтобы JS инициализировал как можно скорее, даже до загрузки содержимого страницы. Но мы хотим, чтобы этот сценарий инициализировался ДО остальных сценариев, которые этого требуют. Это должно быть первым в очереди defer. Но, к сожалению, это не сработает

<!-- we want "jQuery" ASAP and still in "defer" queue. But defer is ignored. -->
<script src="jquery.min.js" async defer></script>

<!-- this doesn't blocks the content and can wait the full page load, but requires "jQuery" -->
<script src="some_jquery_plugin.min.js" defer></script>

В этом примере "some_jquery_plugin.min.js" может быть загружен и выполнен до загрузки jQuery, и произойдет сбой. :(

Таким образом, есть 2 способа решения проблемы: либо использовать только директиву defer, либо объединить все зависимые файлы javascript в один JS.