async または defer 属性のないスクリプト、およびインライン スクリプトは、ブラウザーがページの解析を続行する前に、すぐにフェッチされて実行されます - MDN
JavaScript のブロック特性。実際、ほとんどのブラウザはユーザー インターフェイス (UI) の更新と JavaScript の実行の両方に 1 つのプロセスを使用するため、JavaScript が長いほど、一度に 1 つのプロセスしか発生しません。実行に時間がかかるほど、ブラウザがユーザー入力に自由に応答できるようになるまでの時間が長くなります。 - Nicholas C. Zakas「高性能 JavaScript」上記で引用した 2 つの引用符の意味は、ブラウザが DOM を解析するときの意味です。ドキュメントが検出されると、スクリプト タグ (defer および async 属性なし) が検出されると、すぐにダウンロードされて実行されます。同時に、スクリプト コードの実行が完了するまで、ブラウザによるドキュメントの解析が停止します。このブロック動作は、ブラウザーの UI レンダリング、インタラクティブな動作などがシングルスレッド操作であるために発生します。他方、次のコードのように、スクリプト内のコードが後続のドキュメントの解析に影響を与える可能性があります。
そうですか
これは、ブロック機能はユーザー エクスペリエンスに深刻な影響を及ぼします。 以下にいくつかの最適化ソリューションを示します。
1. Deferred Script (遅延スクリプト)
2. 動的スクリプト要素
html<script type="text/javascript"> document.write("The date is " + (new Date()).toDateString());</script>
jsfunction loadJS(url, callback){ var script = document.createElement('script'); script.type = 'text/javascript'; if(script.readyState){ // 兼容IE的旧版本 script.onreadystatechange = function(){ if(script.readyState == 'loaded' || script.readyState == 'complete'){ script.onreadystatechange = null; callback(); } } } else{ script.onload = function(){ callback(); } } script.src = url; document.getElementsByTagName('head')[0].appendChild(script);}
3. XMLHttpRequest スクリプト インジェクション (XHR 動的挿入)
jsloadJS('a.js', function(){ loadJS('b.js', function(){ loadJS('c.js', function(){ app.init(); }) })})
参考