JavaScript ファイルの読み込みと実行のタイミングを調べる(async, defer)
実験
(1) 実験に使うHTMLコード
<!DOCTYPE html>
<html lang="ja">
<head>
...
<link rel="preload" href="./script-head-preload.js" as="script">
<link rel="preload" href="./script-bottom-preload.js" as="script">
<link rel="preload" href="./defer-bottom2-preload.js" as="script">
<link rel="preload" href="./async-bottom2-preload.js" as="script">
...
<script src="./script-head.js"></script>
<script src="./defer-head.js" defer></script>
<script src="./defer-head2.js" defer></script>
<script src="./async-head.js" async></script>
<script src="./defer-head3.js" defer></script>
...
</head>
<body>
...
<script src="./script-bottom.js"></script>
<script src="./defer-bottom.js" defer></script>
<script src="./defer-bottom2.js" defer></script>
<script src="./defer-bottom2-preload.js" defer></script>
<script src="./async-bottom.js" async></script>
<script src="./async-bottom2-preload.js" async></script>
<script src="./defer-bottom3.js" defer></script>
</body>
</html>
(2) 実験手順
- ブラウザのコンソールを開いて、このページをリロードしてください(キャッシュを削除してから)。
- それぞれの JavaScriptファイルには、
console.log()
で自分自身のファイル名を出力するコードが記述されているので、読み込まれた順番にファイル名が出力されます。
実験の結果
(1) JavaScriptファイルが実行された順番
実行の順番(async以外)
順番 |
スクリプト |
Priority |
説明 |
1 |
script-head.js |
High |
読み込まれたらすぐに実行される。パースをブロックして実行される。 |
2 |
script-head-preload.js |
High |
preload していても関係なく、記述した順番に実行されるようだ。 |
3 |
script-bottom.js |
High |
|
4 |
defer-head.js |
Low |
DOMContentLoadedイベントが発生する直前のタイミングのはず。なので、HTMLパースは完了しているはず。 |
5 |
defer-head2.js |
Low |
|
6 |
defer-head3.js |
Low |
|
7 |
defer-bottom.js |
Low |
|
8 |
defer-bottom2.js |
Low |
|
9 |
defer-bottom2-preload.js |
High |
preload しているので早いタイミングで読み込まれるが、記述した順番に実行される。 |
10 |
defer-bottom3.js |
Low |
|
- 必ず上記の順番で実行される。
async-*.js
ファイルの実行タイミングは、その時によって2番目だったり5番目だったりして不定であった(非同期実行であるため)。
- ただ、
async-head.js
が async-bottom.js
より先に実行された(保証されている?)。
- Priorityは、あくまで「読み込みタイミング」の Priorityである。「実行」ではない。
- 恐らく Priority=High のスクリプト(deferは除く)の実行が終わるまで、最初のレンダリングはブロックされる。
実行の順番(asyncのみ)
順番 |
スクリプト |
Priority |
説明 |
? |
async-bottom2-preload.js |
High |
|
? |
async-head.js |
Low |
|
? |
async-bottom.js |
Low |
|
(2) Chrome の [Network]パネル
(3) Chrome の [Performance]パネル
結論
<head>
内のJavaScriptファイルが先に読み込まれる。
- 基本的には上から順番に読み込まれる。
defer
は、普通の JavaScriptファイルの後で実行される(DOMContentLoaded イベントの直前で実行される)。
defer
は記述した順番で実行される。
async
はいつ実行されるか分からない。しかし、<link rel=preload ...>
で早めに実行させることはできる。
- (
async
あり)以外の script
に preload
を記述しても、実行順序は変わらない。
仕様メモ
scriptタグによる読み込みと実行タイミング
参考