web-dev-qa-db-ja.com

HTMLスクリプトタグでasync属性とdefer属性の両方を使用できますか?

deferasyncの両方を使用して、次のJavaScriptコードをロードしたいと思います。

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

deferはInternet Explorer 5.5以降でサポートされているため、 CanIUse.com で確認できるように、非同期が使用できない場合に遅延を使用するように適切にフォールバックしたいと思います。 Asyncは、利用可能な場合に使用する方が良いと思いますが、Internet Explorer 10まではサポートされていません。

したがって、私の質問は、上記のコードは有効なHTMLですか?そうでない場合、deferが利用できないときにスクリプトでasyncを使用するように適切にフォールバックするJavaScriptを使用してこの状況を作成できますか?

63
Jasdeep Khalsa

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

Async属性が指定されている場合でもdefer属性を指定すると、デフォルトである同期ブロッキング動作ではなく、遅延のみをサポートする(非同期ではない)レガシーWebブラウザーが遅延動作にフォールバックします。

106
dave

問題は、あなたはそれが何をすることを期待しますか? asyncdeferの両方が存在する場合、スクリプトは遅延し、ブラウザーがアイドル状態のときにDOMContentLoadedの後でのみ実行されますが、仕様を正しく読んでいる場合、deferasyncが設定されており、スクリプトは非同期に読み込まれるため、利用可能になるとすぐに実行されます。これは、DOMContentLoadedの前である場合があり、他のリソースをブロックする場合があります。

これらの属性を使用して選択できるモードは3つあります。 async属性が存在する場合、スクリプトは利用可能になるとすぐに非同期で実行されます。 async属性はないがdefer属性はある場合、ページの解析が完了するとスクリプトが実行されます。どちらの属性も存在しない場合、ユーザーエージェントがページの解析を続行する前に、スクリプトがフェッチされてすぐに実行されます。

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

15
Patrick Clancey

はい、有効なHTMLであり、期待どおりに動作します。

W3C準拠のブラウザはasync属性を認識し、スクリプトを適切に処理しますが、レガシー[〜#〜] ie [〜#〜]バージョンはdefer属性を認識します。

両方の属性がbooleanであるため、値を割り当てる必要はありません 。

9
jAndy

残念ながら、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ファイルを1つのJSにマージします。

2