📲

script要素のJavaScript読み込みパターンについて

2022/11/21に公開
2

どうもoreoです。

今回は、script要素のJavaScript読み込みパターンについて整理したいと思います。defer属性やasync属性を使用することで、JavaScriptの読み込みや実行を制御できるので、パフォーマンスを考える上では非常に重要ですね。

1 JavaScript読み込みパターン

JavaScriptの読み込みパターンは、WHATWGで以下のように分かりやすく纏められています。この図を基に解説していきます!

参考 : https://html.spec.whatwg.org/multipage/scripting.html

1-1 何も指定しない場合

この場合、HTMLパーサーがHTMLを先頭から順に解析し、script要素に遭遇すると、解析を中断してJavaScriptの読み込みと実行を行います。JavaScriptの読み込みと実行の間は、解析処理が中断されるため、JavaScriptファイルが大きい場合、webページの表示に時間がかかります。

<script src="./test.js">

1-2 defer属性を指定する場合

defer属性を指定すると、HTML解析と並行してJavaScriptを読み込み、それらが終了した段階でJavaScriptが実行されます。defer属性が付与されたscript要素が複数存在する場合は、script要素の記載順に実行されます。

defer属性を使用する場合、src属性がないと構文エラーとなります。

<script src="./test.js" defer>

1-3 async属性を指定する場合

aync属性を指定すると、HTML解析と並行してJavaScriptを読み込み、JavaScriptの読み込みが終了した段階でHTML解析を中断して、JavaScriptの実行を行い、実行後にHTML解析が再開されます。async属性が付与されたscript要素が複数存在する場合は、defer属性とは異なり、実行順はscript要素の記載順にはなりません。

aync属もdefer属性と同様に、src属性がないと構文エラーとなります。また、defer属性とaync属性を同時に指定すると、aync属性の挙動となります。

<script src="./test.js" async>

1-4 type属性をmodule に指定する場合

type属性の値としてmoduleを指定すると、リソースはモジュールとして読み込まれるようになります(モジュールスクリプトと呼びます)。この場合、defer属性と同じように、HTML解析と並行してJavaScriptを読み込み、それらの読み込みが終了した段階でJavaScriptが実行されます。

<script type="module" src="./test.js">

また、モジュールスクリプトにasync属性を指定した場合は、「1-3 async属性を指定する場合」と同じ挙動となります。

<script type="module" src="./test.js" async>

2 最後に

どの読み込み方を採用するかはケースバイケースだと思いますので、その都度判断できるよに、各々の違いをしっかり理解しておきたいですね。

3 参考

https://html.spec.whatwg.org/multipage/scripting.html

https://www.borndigital.co.jp/book/25999.html

https://qiita.com/phanect/items/82c85ea4b8f9c373d684

Discussion

Nozomu IkutaNozomu Ikuta

非常にわかりやすい記事ありがとうございます!

nitpickですが、 **defer属性と同じ**ように のところ、太字にしようとしてtypoしてるみたいです

oreo2990oreo2990

ikutaさん!コメント&ご指摘ありがとうございました。修正させていただきました!!