スクリプトを動的にロードしていdefer
ないasync
、またはとしてマークしていない場合、スクリプトはページで検出された順序でロードされます。それが外部スクリプトであるかインラインスクリプトであるかは問題ではありません-それらはページで遭遇した順番で実行されます。外部スクリプトの後に来るインラインスクリプトは、それらの前にあるすべての外部スクリプトが読み込まれて実行されるまで保持されます。
非同期スクリプト(非同期として指定されている方法に関係なく)は、予測できない順序で読み込まれて実行されます。ブラウザはそれらを並行してロードし、好きな順序で自由に実行できます。
複数の非同期のものの間で予測可能な順序はありません。予測可能な順序が必要な場合は、非同期スクリプトからのロード通知を登録し、適切なものがロードされたときにjavascript呼び出しを手動でシーケンスすることにより、コード化する必要があります。
スクリプトタグが動的に挿入される場合、実行順序の動作はブラウザによって異なります。このリファレンス記事で、Firefoxの動作を確認できます。簡単に言うと、Firefoxの新しいバージョンでは、スクリプトタグが別の方法で設定されていない限り、デフォルトで動的に追加されたスクリプトタグが非同期になります。
のスクリプトタグasync
は、読み込まれるとすぐに実行されます。実際、ブラウザはパーサーを他のことから一時停止し、そのスクリプトを実行する場合があります。したがって、ほとんどいつでも実行できます。スクリプトがキャッシュされていれば、ほとんどすぐに実行される可能性があります。スクリプトの読み込みに時間がかかる場合、パーサーの完了後に実行される可能性があります。覚えておくべきことの1つasync
は、いつでも実行でき、その時間は予測できないということです。
付きのスクリプトタグdefer
は、パーサー全体が完了するまで待機し、でマークさdefer
れたすべてのスクリプトを、検出された順に実行します。これにより、相互に依存する複数のスクリプトをとしてマークできますdefer
。これらはすべて、ドキュメントパーサーが完了するまで延期されますが、依存関係を維持しながら、発生した順に実行されます。defer
スクリプトは、パーサーが完了した後に処理されるキューにドロップされるようなものだと思います。技術的には、ブラウザは、任意の時点で、バックグラウンドでのスクリプトをダウンロードするかもしれないが、彼らが実行したり、パーサーがページを解析し、解析してマークされていない任意のインラインスクリプト実行中に行われた後まで、パーサをブロックしませんdefer
かをasync
。
その記事からの引用は次のとおりです。
スクリプト挿入スクリプトは、IEとWebKitでは非同期に実行されますが、Operaと4.0より前のFirefoxでは同期的に実行されます。
HTML5仕様の関連部分(新しい準拠ブラウザーの場合)はこちらです。非同期動作については、そこに多くのことが書かれています。明らかに、この仕様は、動作を確認するためにテストが必要になる可能性のある古いブラウザ(または適合しないブラウザ)には適用されません。
HTML5仕様からの引用:
次に、状況を説明する次の最初のオプションに従う必要があります。
要素にsrc属性があり、要素にdefer属性があり、要素に「parser-inserted」のフラグが付けられており、要素にasync属性が
ない場合要素は、リストの最後に追加する必要があります。ドキュメントが要素を作成したパーサーのドキュメントに関連付けられた解析を終了したときに実行されるスクリプト。
フェッチアルゴリズムが完了すると、ネットワーキングタスクソースがタスクキューに配置するタスクは、要素の「パーサー実行可能」フラグを設定する必要があります。パーサーはスクリプトの実行を処理します。
要素にsrc属性があり、要素に「parser-inserted」のフラグが付けられていて、
要素にasync属性がない場合要素は、要素を作成したパーサーのドキュメントの保留中の解析ブロックスクリプトです。(このようなスクリプトは、ドキュメントごとに一度に1つしか存在できません。)
フェッチアルゴリズムが完了すると、ネットワーキングタスクソースがタスクキューに配置するタスクは、要素の「パーサー実行可能」フラグを設定する必要があります。パーサーはスクリプトの実行を処理します。
要素にsrc属性がなく、要素に「パーサー挿入」のフラグが付けられており、スクリプト要素を作成したHTMLパーサーまたはXMLパーサーのドキュメントに、スクリプトをブロックしているスタイルシートがある場合要素は要素を作成したパーサーのドキュメントの保留中の解析ブロックスクリプト。(このようなスクリプトは、ドキュメントごとに一度に1つしか存在できません。)
要素の「パーサー実行の準備完了」フラグを設定します。パーサーはスクリプトの実行を処理します。
エレメントにsrc属性があり、async属性がなく、「force-async」フラグが設定されていない場合、エレメントは、関連付けられているできるだけ早く実行されるスクリプトのリストの最後に追加する必要があります。スクリプトアルゴリズムのドキュメントの準備が開始されたときのスクリプト要素のドキュメント。
フェッチアルゴリズムが完了すると、ネットワークタスクソースがタスクキューに配置するタスクは、次の手順を実行する必要があります。
要素がスクリプトリストの最初の要素ではなく、上記で追加されたできるだけ早く順番に実行される場合は、要素を準備完了としてマークしますが、スクリプトをまだ実行せずにこれらの手順を中止します。
実行:このスクリプトリストの最初のスクリプト要素に対応するスクリプトブロックを実行します。このスクリプトブロックは、できるだけ早く順番に実行されます。
このスクリプトのリストから、できるだけ早く順番に実行される最初の要素を削除します。
できるだけ早く順番に実行されるこのスクリプトのリストがまだ空でなく、最初のエントリが既に準備完了としてマークされている場合は、実行というラベルの付いたステップに戻ります。
エレメントにsrc属性がある場合エレメントは、スクリプトアルゴリズムの準備が開始されたときにスクリプトエレメントのドキュメントのできるだけ早く実行されるスクリプトのセットに追加する必要があります。
フェッチアルゴリズムが完了すると、ネットワークタスクソースがタスクキューに配置するタスクは、スクリプトブロックを実行し、できるだけ早く実行されるスクリプトのセットから要素を削除する必要があります。
それ以外の場合、他のスクリプトがすでに実行されている場合でも、ユーザーエージェントはすぐにスクリプトブロックを実行する必要があります。
JavaScriptモジュールスクリプトについてはどうtype="module"
ですか?
JavaScriptは、次のような構文でモジュールのロードをサポートするようになりました。
<script type="module">
import {addTextToBody} from './utils.mjs';
addTextToBody('Modules are pretty cool.');
</script>
または、src
属性:
<script type="module" src="http://somedomain.com/somescript.mjs">
</script>
のすべてのスクリプトにtype="module"
は、自動的にdefer
属性が与えられます。これにより、他のページのロードと並行して(インラインではない場合)それらがダウンロードされ、パーサーが実行された後、順番に実行されます。
モジュールスクリプトにはasync
、パーサーが完了するまで待機せずasync
、他のスクリプトに関連する特定の順序でスクリプトを実行するのを待たずに、できるだけ早くインラインモジュールスクリプトを実行する属性を与えることもできます。
:ショーはフェッチと、ここで、この記事では、モジュールスクリプトを含むスクリプトの異なる組み合わせの実行ことはかなり便利なタイムラインチャートありますJavascriptのモジュールのロードは。