CODE JavaScript

【徹底解説】scriptタグにdeferやasyncをつけるとどうなる?

いろんなサイトを検証モードで調べてみると、たまにscriptタグの中にdeferという記述を見ることがあるんあだけど、deferってなんだ? この記述を入れるとどうなるんだろう?


他社サイトの構造とかをデベロッパーモードで見てみると<script>タグの中にdeferやasyncという文字列が入ってたりしませんか?

「defer属性」と「async属性」を正しく使うことでJavaScript(以下JS)の読み込みタイミングを調整でき、結果としてページの読み込み速度を改善することができます。

では詳しく解説していきます。

deferとasyncは何者?

deferとasyncは<script>タグ内に記述することができる属性です。

これらの属性はJSファイルの読み込みと実行のタイミングを調整するために使われます。

適切に使うことでWebページの読み込みスピードの改善につながります。

ページ読み込み速度が上がる理由

結論に行く前にまずは通常の<script>の読み込みと実行のタイミングについて理解しましょう。

通常は<script>タグは</body>の閉じタグの前で読み込ませますよね?
どうして<head>で読み込ませたらダメなのでしょうか?

ページ表示速度が落ちるからって聞いた!

そうですね!

ではなぜページ表示速度が遅くなるのでしょうか?
次の図を見てください。

Webの仕様上、ページの読み込みはHTMLの一行目からスタートします。
<head>内にJSを読み込ませてしまうと、解析のかなり序盤でJSファイルを見つけてすぐに読み取りと実行を行います。

そしてその間はHTMLの読み取りは一時停止してしまいます。
JSの読み取りと実行が完了し次第HTMLの読み取りが再開されます。

この状況だとページ表示が遅れるだけでなく、DOMの読み込みが未完の状態でJSを実行しているのでJSがDOM操作を行っているとエラーになったりします。

だから<head>内に入れるのではなく、</body>直前にJSを読み込ませるのです。
一応</body>直前にJSを読み込ませたパターンの画像も入れておきます。

これでHTMLの読み取りを中断させることなく完了させることができますし、JSの読み取りと実行にも問題が無いということですね。

がしかし!!

async属性とdefer属性を使うことでHTMLの解析をしながら同時にJSを読み込むことを可能にし、結果としてページの読み込み速度を改善させられるのです。

ちょっといい async属性

async属性をつけて<head>内に記述するとどのようにページの読み込みがされるかというと、下図のようになります。

図からわかるようにasync属性をつけるとHTML解析をしながら同時にJSの読み取りを行ってくれます。
しかしJSの読み取り完了後はすぐに実行移ります。
その時はHTMLは一時停止してしまいます。

何もつけないよりはページの読み込み速度は早いですが、JSの実行に関してはこちらもDOMの読み込みが未完の状態でJSを実行しているので良く無いですね。
DOM操作をする記述があればエラーになってしまいます。

全ての問題を解決してくれるのがdeferです。

めちゃくちゃいい defer属性

defer属性をつけることで、JSの読み取りはasync属性の時と同様にHTML解析と同時に並行して行ってくれます。
さらにHTMLの読み込みが完了してからJSの実行が始まります。

これでならDOM読み込みが完了しているので問題は起きませんね。

こうした理由から私は基本的にdeferを設定しています。

async/deferを使用する際の注意点

<script>タグにasync/defer属性を入れるときは、<script>タグは<head>内に入れ込みましょう。

理由はHTMLの読み込みと並行してJSの読み込みを行ってくれるからです。
HTMLとJSを同時並行で読み取ってくれるのであればわざわざHTMLの最後に書いてHTMLの読み込みが終わってからJSを読み込みを開始させるのは意味がないですよね。

またasync属性の特徴として、複数のJSファイルを読み込む場合はダウンロードが早く完了したものから実行されてしまいます。
ライブラリーを先に読み込ませないといけない時に自分のスクリプトが先に読み込みが完了してしまうと、エラーになってしまうことがあります。

しかし、defer属性は上から順番に読み込みをしていくのでこちらの意図通りの順番に複数のJSを読み込ませることが可能になります。

こういった特徴があるのでdefer属性を使うことをオススメします。

まとめ

最後に今回紹介した読み込みパターンを比較してみましょう。

async属性とdefer属性を適切に使用することでページの読み込み速度が上がります。

経験的にdefer属性を使用しているのが一番いいかと思います。

今回のdefer/asyncだけでなくJavaScriptの基本を詳細に解説している本を紹介します。
400ページ以上あり細かいことまで解説しているので、本気で学びたい人におすすめです▼▼

js textbook

初めてのJavaScript 第3版 ES2015以降の最新ウェブ開発 ¥3,520 ★★★★☆(2022年9月18日現在)

Amazonで探す





今回は以上となります。
皆さんのJSの理解に繋がっていれば幸いです。
では!




▼▼あわせて読みたいの記事▼▼

【JS】 DOMContentLoaded と load の違いを新人でもわかるように解説

-CODE, JavaScript
-, , , ,