[JavaScript, HTML] script要素が実行される順番:基本は関数と同じ
静的にHTMLに記述する場合
- 基本は、先に記述されたscript要素から順に実行されていく。
- head要素に書くか、body要素に書くかは関係がない。
- script内の処理をしている間は他の処理は止まり、HTMLの(画面の)レンダリングもストップする。
JavaScriptは基本的にシングルスレッドで、関数単位で実行されていき、非同期の処理は準備ができたものから順に、現在実行中の関数が終了してから実行される。
その説明についてはこちら。
コードをscript内に直接記述する場合
では、以下のように先に記述されたscriptタグの中で、すぐ準備される非同期の関数が存在した場合はどうなるか。
<script type="text/javascript"> var a = "1"; setTimeout(function () { a += "2"; }, 0); </script> <script type="text/javascript"> a += "3"; </script> <script type="text/javascript"> alert(a); </script>
seTimeout()の時間指定をゼロにすることで、それに指定した非同期の無名関数がすぐ準備完了になるようにしている。
結果は「123」と出力される。
つまり、一連のscript要素の処理がひとまとめに実行されるのではなく、それぞれの要素が一種の関数のように実行され、ひとつのscriptの処理が終わったあと、その時点で準備が完了した非同期の関数があれば、それが実行されてから次のscriptへ移る。
1番目のscript=>準備のできた非同期関数=>2番目のscript
コードをファイルから読み込む場合
この場合も上記と同様。
よって、読み込みに時間がかかるファイルを指定した場合、それがロードされて実行が完了するまで他の処理は止まってしまう。
非同期処理
async属性
指定したファイルを非同期で読み込み、ロードが完了した段階で現在実行中のscriptの処理が終わったあとに実行される。
defer属性
指定したファイルを非同期で読み込み、ページのすべてのHTMLが読み込まれ、レンダリングが完了したあとに実行される。
動的にHTMLに追加する場合
headやbodyに、JavaScriptでscriptを追加した場合、async属性などをつけなくてもデフォルトで非同期処理になる。
この場合、追加するscriptにsrcでファイルを指定しているか、要素内に直接コードを記述しているかは関係ない。