JavaScriptのasyncとdeferの違い|読み込みを最適化して表示速度を改善

コードが書かれたモニター

JavaScriptを外部ファイルとして読み込むとき、何気なく次のようなコードを書いていないでしょうか。

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

もちろん、この書き方でもJavaScriptは読み込まれます。

ただし、読み込む場所やファイルの内容によっては、ページの表示が遅くなったり、HTML要素がまだ存在しないタイミングでJavaScriptが実行されてエラーになったりすることがあります。

そこで使われるのが、async と defer です。どちらもJavaScriptの読み込みを効率化するための属性ですが、動き方はかなり違います。

この記事では、JavaScriptのasyncとdeferの違い、使い分け、WordPressサイトでの注意点、PageSpeed Insights改善との関係をわかりやすく解説します。

JavaScriptの読み込みが表示速度に影響する理由

HTMLは、上から順番に読み込まれていきます。

その途中で通常のscriptタグが出てくると、ブラウザはHTMLの解析を一時停止し、JavaScriptファイルを取得して実行します。

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

この場合、JavaScriptの読み込みや実行が終わるまで、HTMLの解析が止まることがあります。

その結果、以下のような問題が起こる可能性があります。

  • ページの表示開始が遅くなる
  • ファーストビューの描画が遅れる
  • DOM要素が存在しない状態でJavaScriptが実行される
  • PageSpeed Insightsで改善項目として指摘される

特に、ファーストビューに関係ないJavaScriptを早い段階で読み込んでいると、表示速度に悪影響が出やすくなります。

asyncとは

asyncは、JavaScriptファイルをHTML解析と並行してダウンロードし、ダウンロードが完了したタイミングですぐ実行する属性です。

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

特徴は次の通りです。

  • HTML解析と並行してJavaScriptをダウンロードする
  • ダウンロードが終わったらすぐ実行される
  • 実行順は保証されない
  • DOMContentLoadedを待たない
  • DOM操作を行うスクリプトには注意が必要

つまり、asyncは「読み込み終わったらすぐ実行していいJavaScript」に向いています。

asyncに向いているスクリプト

asyncに向いているのは、他のスクリプトやDOM要素への依存が少ないものです。

  • アクセス解析タグ
  • 広告タグ
  • 外部サービスの計測タグ
  • 単独で動作する第三者スクリプト

たとえば、Google Analyticsや広告関連のタグでasyncが使われることがあります。

ただし、他の処理に依存するJavaScriptや、HTML要素を操作するJavaScriptには向いていない場合があります。

deferとは

deferは、JavaScriptファイルをHTML解析と並行してダウンロードし、HTMLの解析が終わってから実行する属性です。

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

特徴は次の通りです。

  • HTML解析と並行してJavaScriptをダウンロードする
  • HTML解析が終わってから実行される
  • 複数のdefer付きscriptは記述順に実行される
  • DOM操作を行うスクリプトと相性がよい
  • DOMContentLoadedの直前に実行される

deferは、通常のサイト制作ではかなり使いやすい属性です。

HTMLの読み込みを邪魔しにくく、DOMが準備された状態で実行されるため、メニュー、アコーディオン、スライダー、フォーム制御などにも使いやすいです。

asyncとdeferの違い

asyncとdeferの違いを表にすると、次のようになります。

項目 async defer
ダウンロード HTML解析と並行 HTML解析と並行
実行タイミング 読み込み完了後すぐ HTML解析完了後
実行順 保証されない 記述順に実行
DOM操作 注意が必要 比較的向いている
向いている用途 解析・広告など独立した処理 サイト本体のJavaScript

迷った場合は、サイト本体のJavaScriptにはdeferを使う方が安全です。

通常のscript、async、deferの違いをコードで比較

通常のscript

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

HTML解析の途中で読み込みと実行が行われます。
配置場所によっては、ページ表示やDOM操作に影響します。

async

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

HTML解析と並行して読み込み、読み込みが終わったらすぐ実行します。
実行順が重要なスクリプトには不向きです。

defer

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

HTML解析と並行して読み込み、HTML解析が終わってから実行します。
複数のスクリプトがある場合も、記述順に実行されます。

asyncを使うときの注意点

asyncは便利ですが、使い方を間違えると不具合の原因になります。

特に注意したいのは、以下のようなケースです。

  • jQuery本体より先にjQuery依存スクリプトが実行される
  • DOM要素がまだ存在しない状態で処理が走る
  • 複数のJavaScriptの実行順が前後する
  • スライダーやメニューが動かなくなる

たとえば、次のような指定は危険です。

<script src="jquery.js" async></script>
<script src="custom.js" async></script>

この場合、custom.jsがjquery.jsより先に実行される可能性があります。custom.jsがjQueryに依存している場合、エラーになるので注意しましょう。

deferを使うときの注意点

deferは扱いやすいですが、何でも付ければよいわけではありません。

次の点には注意しましょう。

  • インラインスクリプトには基本的に使わない
  • 古い外部スクリプトで動作前提が違う場合がある
  • 広告タグや解析タグは提供元の推奨コードを確認する
  • WordPressプラグインが出力するスクリプトを無理に変更しない

特にWordPressでは、テーマやプラグインがJavaScriptを出力しています。すべてに一括でdeferを付けると、一部の機能が動かなくなることがあります。

WordPressでasyncやdeferを使う場合

WordPressでは、wp_enqueue_script()を使ってJavaScriptを読み込むのが基本です。テーマ内で直接scriptタグを書くより、WordPressの仕組みに合わせた方が管理しやすくなります。

たとえば、テーマのJavaScriptを読み込む場合は以下のようにします。

function my_theme_scripts() {
  wp_enqueue_script(
    'theme-main',
    get_template_directory_uri() . '/js/main.js',
    array(),
    '1.0.0',
    true
  );
}
add_action('wp_enqueue_scripts', 'my_theme_scripts');

最後のtrueは、フッター側に読み込む指定です。

最近のWordPressでは、スクリプト読み込み時に属性を指定する方法も用意されています。テーマやWordPressのバージョンに合わせて、deferやasyncを適切に付けるとよいです。

ただし、すべてのスクリプトへ機械的に付けるのはおすすめしません。

PageSpeed Insights対策としての考え方

PageSpeed Insightsでは、JavaScriptの読み込みや実行が表示速度に影響している場合があります。特に、以下のようなチェックに関係することがあります。

  • レンダリングを妨げるリソースの除外
  • 未使用のJavaScriptの削減
  • メインスレッド作業の短縮
  • LCPの改善

ただし、asyncやdeferを付ければ必ずスコアが上がるわけではありません。重要なのは、以下のように整理することです。

  • ファーストビューに不要なJavaScriptは遅らせる
  • 依存関係があるJavaScriptは実行順を守る
  • 不要なプラグインのスクリプトを読み込まない
  • 広告・解析タグは提供元の推奨方法を確認する
  • 変更後は実機で動作確認する

表示速度を改善するには、属性の追加だけでなく、JavaScriptそのものを減らすことも大切です。

asyncとdeferの使い分けまとめ

基本的な使い分けは次の通りです。

スクリプトの種類 おすすめ
アクセス解析 async
広告タグ 提供元の推奨に従う
DOM操作を行う自作JS defer
jQuery依存のJS deferまたはフッター読み込み
他のJSに依存しない外部タグ async

迷った場合は、サイト本体のJavaScriptにはdefer、独立した解析タグにはasyncと考えると分かりやすいです。

参考:MDN:script 要素

まとめ

asyncとdeferは、どちらもJavaScriptの読み込みを効率化するための属性です。

ただし、動き方は違います。

  • asyncは読み込み完了後すぐ実行される
  • deferはHTML解析完了後に実行される
  • asyncは実行順が保証されない
  • deferは記述順に実行される
  • DOM操作を行う自作JavaScriptにはdeferが使いやすい

JavaScriptの読み込みは、ページの表示速度や動作安定性に関わります。特にWordPressでは、テーマ・プラグイン・広告・解析タグなど、複数のJavaScriptが読み込まれがちです。

何でも一括で遅延すればよいわけではないので、スクリプトの役割ごとにasyncとdeferを使い分けることを意識して使ってみてください。