Является ли атрибут/свойство "асинхронный" полезным, если динамически добавлен 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.