web-dev-qa-db-ja.com

スクリプトがDOMに動的に追加される場合、「async」属性/プロパティは役に立ちますか?

この質問は、 どのブラウザが<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に動的に追加する一般的な方法であり、Steve Soudersの著書「 Even Faster Web Sites 」のIIRCは、すべての最新のブラウザーにスクリプトを非同期でロードするように促します(つまり、ページをブロックしない)後続のアセットのレンダリングまたはダウンロード)。

私がそれで正しければ、s.async = trueステートメントは役に立ちますか?動的に追加されたスクリプトはすでに非同期ダウンロードをトリガーするはずなので、そのプロパティをサポートするブラウザーであっても、冗長ではないでしょうか。

32
Bungle

仕様 (現在)は、ではないパーサーが挿入したscript要素が非同期であることを示しています。 asyncプロパティは、パーサーが挿入されていないscript要素とは無関係です。

3つ目は、要素が「force-async」になるかどうかを示すフラグです。最初に、script要素にこのフラグを設定する必要があります。これは、挿入するscript要素のHTMLパーサーとXMLパーサーによって設定されません。さらに、「force-async」フラグが設定されているスクリプト要素にasync content属性が追加されている場合は常に、要素の「force-async "フラグを設定解除する必要があります。

もちろん、async content属性があるということは、スクリプトが非同期で実行されることを意味します。仕様言語らしいスクリプトの同期実行を強制する機会を残します(属性を設定してから削除することにより)が、実際には機能せず、おそらく少しあいまいです。スペックパーサーが挿入されていないscript要素は非同期です。

この指定された動作は、IEおよびChromeは常に実行され、Firefoxは何年も実行され、現在のOperaも実行されます) (上記のリンクの回答の古い動作からいつ変更されたかはわかりません)。

簡単にテストできます。

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

... with script.js であること

console.log("script loaded");

...ログに記録します

 a 
 b 
スクリプトが読み込まれました
14
T.J. Crowder

問題はs.async = true動的に挿入されたスクリプトを使用するか、これらはすでに非同期でロードされています。答えは、説明されているように、それらはすべてのブラウザに非同期でロードされないということです ここ (リンクを提供してくれたMarkus Olssonに感謝します)

スクリプトが挿入されたスクリプトは、IEおよびWebKitでは非同期に実行されますが、Operaおよび4.0より前のFirefoxでは同期的に実行されます。Firefox4.0では、非同期DOMプロパティはデフォルトでtrueになりますスクリプトで作成されたスクリプトの場合、デフォルトの動作はIEおよびWebKitの動作と一致します。

asyncをサポートしているが、デフォルトで非同期読み込みが行われていないブラウザ(Firefox 3.6など)では、async = true違いがあります。

(上記のリンクは、Firefox3.6で使用されるレイアウトエンジンであるGecko1.9.2で非同期がサ​​ポートされていることを確認しています)

21
Tim Goodman

興味深い-私は自分の仮定が間違っていたことがわかったと思います。

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

3
Bungle

私はあなたが正しいと信じています。

スティーブ自身の例 では、スクリプトタグをhead要素にアタッチする前にasync属性を設定していません。

async atttribute についての私の理解は、document.writeを使用してページを操作するつもりがないことをブラウザーに通知する方法であり、ロードを停止する代わりにレンダリングを続行できるようにすることです。脚本。 mdcのscript要素 のドキュメントを参照してください。このドキュメントには、document.write/asyncの問題についてもう少し詳しく説明されています。

あなたのテクニックでは、ページの存続期間のどこにスクリプトがロードされるかを知る方法がないので、とにかくdocument.writeを使用すべきではないことに注意してください。

1
Markus Olsson