<script>の実行タイミングについての細かな動作は仕様に規定されています。
[https://html.spec.whatwg.org/multipage/scripting.html#prepare-a-script](https://html.spec.whatwg.org/multipage/scripting.html#prepare-a-script)
以下、内容を大まかに説明したいと思います。
(teratailでの回答は初めてで、文字装飾に慣れてなく文章が読みづらいかもしれませんが、ご容赦ください)
---
script要素には、以下のような方法で2つに分類することができます。
**[1] HTMLを解析する際に生じるscript要素**
例:HTMLに <script>alert();</script> などと書いてあるもの
[2] 動的に生成して生じるscript要素
例:document.createElement("script") してDOMに挿入したもの
(内部的には、[1]のみに"parser-inserted"というフラグを付けることで区別されています)
また、以下のような分類も可能です。
[A] src属性を持つもの
例:<script src="hoge.js"></script>
[B] src属性を持たずに要素内にテキストを持つもの
例:<script>alert("!");</script>
これらの分類は互いに独立しています。つまり、あるscript要素は、[1]かつ[A]であったり、[2]かつ[B]であったります。
(今回の質問の場合であれば[2]かつ[A]ですね。)
そして、上の2種類の分類によって、script要素のコードが実行されるタイミングが変化するのです。
[1]かつ[A]:https://html.spec.whatwg.org/multipage/scripting.html#script-processing-parser-inserted
つまり、HTMLに<script src="hoge.js"></script>と直書きされているもの。
この場合、DOMのレンダリングが一旦中断され、外部スクリプトが読み込まれて実行された後に、DOMレンダリングが再開されます。
こういうscript要素を pending parsing-blocking script ともいいます。
[1]かつ[B]:https://html.spec.whatwg.org/multipage/scripting.html#script-processing-inline
つまり、HTMLに<script>alert("!");</script>と直書きされているもの。
この場合、DOMのレンダリングが一旦中断され、スクリプトが実行された後に、DOMレンダリングが再開されます。
[2]かつ[A]:https://html.spec.whatwg.org/multipage/scripting.html#script-processing-src
今回のご質問のパターンです。
つまり、動的に以下のようにscript要素を生成した場合です。
var s = document.createElement("script");
s.src = "xxx.js";
document.body.appendChild(s);
この場合、スクリプトの読み込みが完了し次第、実行されます。
DOMレンダリングは即座には中断されませんが、レンダリング途中であっても読み込みが完了すればその時点で実行されます。
こういうscript要素は set of scripts that will execute as soon as possible というリストに追加され、読み込みが完了次第実行されるという仕組みになっています。
[2]かつ[B]:https://html.spec.whatwg.org/multipage/scripting.html#script-processing-inline
つまり、動的に以下のようにscript要素を生成した場合です。
var s = document.createElement("script");
s.text = "alert(123)";
document.body.appendChild(s);
この場合、実行DOMのレンダリングはもちろんscript要素を追加したスクリプトも一旦中断され、スクリプトが実行された後に、DOMレンダリングが再開されます。
Document内のどこでもいいので、要素を追加した時点で即座に実行されます。
asyncやdefer属性なども考えるとさらに複雑になりますが、今回の質問の範囲であればこのあたりの説明で十分かと思います。
かなりややこしいですが、ご参考になれば幸いです。
ちなみに、非同期で読み込みたいのであればasync属性を追加してやるだけで十分です。(IE9以下非対応ですが)
おおよそ[2]かつ[A]と同じようになります。
lang
1<script src="xxx.js" async></script>
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2015/04/27 11:36
2015/04/28 10:20
2015/04/28 13:23