JavaScriptのdeferとasync、そしてCore Web Vitalsへの影響
Core Web Vitalsで最高の結果を得るために、JavaScriptのasyncとdeferの使い分けを学びましょう。
JavaScriptのDeferとAsyncの違いとCore Web Vitalsへの影響
クライアントのCore Web Vitalsを監査すると、ページ内でパーサーブロック(sync)、非同期(async)、遅延(defer)JavaScriptが区別されていないケースを頻繁に目にします。スクリプトごとに最適な読み込みタイミングは異なるため、これは改善すべき問題です。
最終レビュー:Arjen Karel(2026年3月)
Table of Contents!
2025 Web Almanacによると、render blockingリソースの監査に合格するモバイルページはわずか15%です。中央値のページは22個のスクリプト(合計630 KB以上)を読み込みますが、そのうち251 KBのJavaScriptは完全に未使用です。大半のサイトは多すぎるJavaScriptを、間違ったタイミングで読み込んでいます。
要約
ページのheadにある「通常の」JavaScriptは、ダウンロードと実行が完了するまでブラウザのHTMLパースをブロックします。asyncスクリプトはバックグラウンドでダウンロードされますが、準備ができるとすぐに実行されるため、パースを中断する可能性があります。deferスクリプトはバックグラウンドでダウンロードされ、パースが完了するまで待機してからドキュメント順に実行されます。
DOMを操作するスクリプトにはdeferを使用します。完全に独立したスクリプト(アナリティクスやトラッキングピクセルなど)にはasyncを使用します。ページがレンダリングされる前に実行必須のスクリプトに限り、どちらも使用しないでください(sync)。迷った場合はdeferを使用してください。

1. 同期JavaScript(sync)
デフォルトでは、ページのheadにあるスクリプトは同期的に動作します。ブラウザは同期スクリプトを見つけるとHTMLのパースを停止し、スクリプトのダウンロードと実行を終えてから処理を再開します。つまり、すべての同期スクリプトが完了するまでピクセルは描画されません。容量が大きいスクリプトや遅いスクリプトの場合、これによりFirst Contentful Paintに目に見える遅延が生じます。
<!DOCTYPE html>
<html>
<head>
<title>Sync JavaScript Example</title>
<script src="script1.js"></script>
<script src="script2.js"></script>
</head>
<body>
<!-- Page content here -->
</body>
</html>
ブラウザはscript2.jsに着手する前に、script1.jsをダウンロードして実行しなければなりません。その間、何もレンダリングされません。2025年現在、モバイルページの中央値ですでにTotal Blocking Timeは約2秒に達しています。head内の同期スクリプトは、この状況をさらに悪化させます。
2. 非同期JavaScript(async)
async属性を追加すると、ブラウザはHTMLのパースを続けながらバックグラウンドでスクリプトをダウンロードします。スクリプトはダウンロードが完了次第、その時点でパーサーがどこにいようと即座に実行されます。パースが一時停止するのは実行中のみです。
<!DOCTYPE html>
<html>
<head>
<title>Async JavaScript Example</title>
<script src="script1.js" ></script>
<script src="script2.js" ></script>
</head>
<body>
<!-- Page content here -->
</body>
</html>
asyncスクリプトは実行順序を保証しません。ダウンロードが早く終わったスクリプトから順に実行されます。script2.jsがscript1.jsに依存している場合、asyncを使用すると予測不可能な不具合を引き起こします。asyncは、スクリプト同士およびDOMから完全に独立している場合にのみ使用してください。
注意すべき点が1つあります。Chromeでは、asyncスクリプトのネットワーク優先度はデフォルトでLowになります。つまり、ブラウザがスクリプトのダウンロードを開始するタイミングが想定より遅くなる可能性があります。asyncスクリプトを(パースをブロックせずに)素早く読み込みたい場合は、fetchpriority="high"を追加してください。
3. 遅延JavaScript(defer)
defer属性もスクリプトをバックグラウンドでダウンロードしますが、HTMLドキュメントのパースが完全に終わるまで実行を延期します。deferスクリプトはドキュメント順に、DOMContentLoadedイベントが発火する直前に実行されます。
<!DOCTYPE html>
<html>
<head>
<title>Defer JavaScript Example</title>
<script src="script1.js" ></script>
<script src="script2.js" ></script>
</head>
<body>
<!-- Page content here -->
</body>
</html>
ほとんどのスクリプトにおいて、deferはより安全な選択です。スクリプトの実行時にはDOMが完全に利用可能であり、実行順序も維持され、最初の描画もブロックされません。The Telegraphはすべてのスクリプトにdeferを適用し、広告の読み込み時間を4秒短縮しました。
4. モジュールスクリプト
ESモジュール(<script type="module">)を使用すると、自動的にdeferと同じ挙動になります。モジュールスクリプトはバックグラウンドでダウンロードされ、パース完了後に実行され、順序を維持します。すでにデフォルトの挙動であるため、明示的にdeferを追加しても効果はありません。
パースの完了を待たず、依存関係グラフが解決され次第すぐにモジュールスクリプトを実行させたい場合は、asyncを追加できます。
比較表
| 属性 | ダウンロード | 実行 | パースをブロックするか? | 順序は維持されるか? |
|---|---|---|---|---|
なし (sync) | ダウンロード中はパースをブロック | ダウンロード直後 | はい(ダウンロード+実行) | はい |
async | バックグラウンド | ダウンロード完了次第 | 実行中のみ | いいえ |
defer | バックグラウンド | HTMLパース後、DOMContentLoaded前 | いいえ | はい |
type="module" | バックグラウンド | HTMLパース後(deferと同じ) | いいえ | はい |
よくある質問
同じタグでasyncとdeferの両方を使用するとどうなりますか? asyncが優先されます。defer属性は完全に無視されます。この記述はIE9のフォールバックとして使われていましたが、2026年現在、両方を使用する理由はありません。
asyncとdeferはインラインスクリプトでも機能しますか? いいえ。従来のインラインスクリプト(srcなし)では、両方の属性が無視されます。外部スクリプトでのみ機能します。例外は<script type="module">で、インラインであってもデフォルトで遅延(defer)されます。
bodyの最後にスクリプトを配置するよりdeferの方が良いですか? はい。<head>内のdeferスクリプトは、すぐに(HTMLパースと並行して)ダウンロードを開始します。bodyの末尾にあるスクリプトは、パーサーがそこに到達するまでダウンロードを開始できません。deferを使用すれば、早期の検出と実行の遅延という両方のメリットを得られます。
asyncとdeferがCore Web Vitalsに与える影響
同期スクリプトは、完了するまで何も描画されないため、FCPを直接的に悪化させます。また、スクリプトが完了するまでLCP要素をレンダリングできない場合、LCPにも悪影響を及ぼします。
asyncスクリプトはFCPを改善します(ダウンロードによって最初の描画がブロックされません)。しかし、ユーザーのインタラクション中に実行され、main threadをブロックした場合、INPの問題を引き起こす可能性があります。
deferスクリプトは初期レンダリングに全く干渉しないため、最高のペイント指標をもたらします。トレードオフとして、ページがコンテンツの表示をJavaScriptに依存している場合(シングルページアプリケーションなど)、パース後にスクリプトが実行されるまでコンテンツが表示されないため、deferは結果的にLCPを遅延させる可能性があります。
CoreDashのモニタリングデータによると、クリティカルではないすべてのスクリプトをsyncからdeferに移行したサイトでは、FCPが平均340ミリ秒改善しました。
さらに一歩進めて:オンデマンドでスクリプトを読み込む
asyncとdeferはパーサーをブロックしないことでページを高速化できますが、スクリプトの遅延がすべての問題を解決するわけではない点に注意が必要です。たとえば、Largest Contentful Paintの要素は、deferやasyncスクリプトによるネットワークやCPUのリソース競合の影響を受けやすくなります。また、Interaction to Next Paintも、ページ読み込みの初期段階で実行されるスクリプトの影響を受けます。そのため、可能な限りスクリプトをオンデマンドで読み込み、ページのパフォーマンスへの影響をより細かく制御すべきです。スクリプトをオンデマンドで読み込む方法をお読みください。
JavaScriptの読み込み戦略の全体像については、JavaScriptを遅延させる16の方法をご覧ください。Lighthouseのrender blockingリソースの警告に対処する場合、そのガイドで解決策を解説しています。また、JavaScriptの優先度レベルを利用して読み込みを微調整したり、headとfooterにおける最適なスクリプト配置を選択したりすることも可能です。