Является ли атрибут/свойство "асинхронный" полезным, если динамически добавлен script в DOM?

Этот вопрос является своего рода касательной. Какие браузеры поддерживают <script async = "async"/>? ,

В последнее время я видел несколько сценариев, которые делают что-то вроде этого:

var s = document.createElement('script');
s.type = 'text/javascript';
s.async = true;
s.src = 'http://www.example.com/script.js';
document.getElementsByTagName('head')[0].appendChild(s);

Это распространенный способ динамического добавления сценария в DOM, который IIRC из книги Стива Соудерса " Даже более быстрые веб-сайты " предлагает всем современным браузерам загружать сценарий асинхронно (т.е. Не блокировать рендеринг страницы или загрузку последующих ресурсов).,

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

Ответ 1

Спецификация (сейчас) диктует, что элемент script который не вставлен парсером, является асинхронным; свойство async имеет отношения к элементам script вставки парсера:

Третий - флаг, указывающий, будет ли элемент " принудительно асинхронным ". Первоначально элементы script должны иметь этот флаг установлен. Он сбрасывается парсером HTML и парсером XML на элементы script которые они вставляют. Кроме того, каждый раз, когда элемент сценария флаг которого "сила-асинхронному" установлен имеет async атрибут содержимого добавлен флаг "сила-асинхронному" элемент должен быть снят.

Конечно, async атрибута содержимого означает, что скрипт будет выполняться асинхронно. Язык спецификации, кажется, оставляет возможность принудительного синхронного выполнения сценария (путем установки атрибута и последующего его удаления), но на практике это не работает и, вероятно, представляет собой лишь некоторую неопределенность в спецификации. Не вставленные парсером элементы script являются асинхронными.

Это заданное поведение - то, что IE и Chrome всегда делали, Firefox делал годами, и нынешняя Opera тоже (я понятия не имею, когда он изменился по сравнению со старым поведением в ответе, связанном выше).

Это легко проверить:

var script = document.createElement("script");
script.src = "script.js";
console.log("a");
document.body.appendChild(script);
console.log("b");

... с использованием script.js

console.log("script loaded");

... войдет

a
b
script loaded

Ответ 2

Вопрос в том, можно ли использовать s.async = true для динамически вставляемых скриптов или они уже загружены асинхронно. Ответ заключается в том, что они не загружаются асинхронно во всех браузерах, как объясняется здесь (спасибо Маркусу Олссону за ссылку)

Сценарии с вставленными сценариями выполняются асинхронно в IE и WebKit, но синхронно в Opera и Firefox до 4.0. В Firefox 4.0 асинхронное свойство DOM по умолчанию имеет значение true для сценариев, созданных сценариями, поэтому поведение по умолчанию соответствует поведению IE и WebKit.

В браузерах, которые поддерживают async но еще не по умолчанию асинхронную загрузку (например, Firefox 3.6), async = true имеет значение.

(Приведенная выше ссылка подтверждает, что async поддерживается в Gecko 1.9.2, движке раскладки, используемом Firefox 3.6)

Ответ 3

Интересно - я думаю, оказывается, что я ошибался в своих предположениях.

Основываясь на этом потоке в форуме разработчиков jQuery:

http://forum.jquery.com/topic/jquery-ajax-async-vs-html5-script-async

похоже, что свойство async было обнаружено для влияния на динамически добавленные скрипты, по крайней мере в Firefox (и, возможно, в Opera, хотя еще не поддерживает свойство).

В теме форума также упоминается реализация асинхронного кода отслеживания Google, которая, хотя кажется, использует свойство async в соответствующем контексте, на самом деле кажется, что синтаксис неверен. Google использует:

ga.async = true;

когда, по-видимому, это не работает; правильный метод должен был бы использовать:

ga.async = 'async';

или

ga.setAttribute('async', 'async');

Итак, исходя из моего нынешнего понимания, не все браузеры будут фактически запускать динамически добавленные скрипты сразу после их вставки в DOM во всех случаях; Для Firefox (и, в конечном счете, для Opera) потребуется свойство async, которое будет установлено для обеспечения того, чтобы это всегда происходило.

Дополнительная информация о реализации Firefox async здесь:

https://bugzilla.mozilla.org/show_bug.cgi?id=503481

Ответ 4

Я считаю, что ты прав.

В Собственные примеры Steve он не устанавливает атрибут async перед прикреплением тега script к элементу head.

Мое понимание async atttribute заключается в том, что это способ сигнализировать браузеру, что вы не собираетесь манипулировать страницей используя document.write, чтобы он мог продолжить рендеринг вместо остановки для загрузки script. См. Документацию для элемента script в mdc, который содержит немного больше проблем document.write/async.

Обратите внимание, что с вашей техникой вы все равно не должны использовать document.write, так как у вас нет возможности узнать, где в течение жизни страницы будет загружен ваш script.