defer
とasync
の両方を使用して、次のJavaScriptコードをロードしたいと思います。
<script defer async src="/js/somescript.js"></script>
defer
はInternet Explorer 5.5以降でサポートされているため、 CanIUse.com で確認できるように、非同期が使用できない場合に遅延を使用するように適切にフォールバックしたいと思います。 Asyncは、利用可能な場合に使用する方が良いと思いますが、Internet Explorer 10まではサポートされていません。
したがって、私の質問は、上記のコードは有効なHTMLですか?そうでない場合、defer
が利用できないときにスクリプトでasync
を使用するように適切にフォールバックするJavaScriptを使用してこの状況を作成できますか?
仕様から: https://www.w3.org/TR/2011/WD-html5-20110525/scripting-1.html#attr-script-async
Async属性が指定されている場合でもdefer属性を指定すると、デフォルトである同期ブロッキング動作ではなく、遅延のみをサポートする(非同期ではない)レガシーWebブラウザーが遅延動作にフォールバックします。
問題は、あなたはそれが何をすることを期待しますか? asyncとdeferの両方が存在する場合、スクリプトは遅延し、ブラウザーがアイドル状態のときにDOMContentLoadedの後でのみ実行されますが、仕様を正しく読んでいる場合、deferはasyncが設定されており、スクリプトは非同期に読み込まれるため、利用可能になるとすぐに実行されます。これは、DOMContentLoadedの前である場合があり、他のリソースをブロックする場合があります。
これらの属性を使用して選択できるモードは3つあります。 async属性が存在する場合、スクリプトは利用可能になるとすぐに非同期で実行されます。 async属性はないがdefer属性はある場合、ページの解析が完了するとスクリプトが実行されます。どちらの属性も存在しない場合、ユーザーエージェントがページの解析を続行する前に、スクリプトがフェッチされてすぐに実行されます。
https://www.w3.org/TR/2011/WD-html5-20110525/scripting-1.html#attr-script-async
はい、有効なHTMLであり、期待どおりに動作します。
W3C準拠のブラウザはasync属性を認識し、スクリプトを適切に処理しますが、レガシー[〜#〜] ie [〜#〜]バージョンはdefer属性を認識します。
両方の属性がbooleanであるため、値を割り当てる必要はありません 。
残念ながら、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にマージします。