defer・async・無指定で実行順が変わる
scriptタグには大きく3つの読み込み方があります。無指定なら見つけた場所でその場で実行、deferならHTMLの解析を止めずに後でまとめて書いた順に実行、asyncなら読み込めたものから順不同で即実行です。この違いを知らないと、書いた順に動くつもりが裏切られます。
特にasyncは読み込み完了の早い順に実行されるため、ファイルサイズやネットワーク状況で順番が毎回変わります。依存関係があるスクリプトにasyncを使うと、たまたま動いたり動かなかったりという不安定さの原因になります。
依存関係があるときに壊れる仕組み
あるスクリプトが別のスクリプトの定義した関数や変数に依存している場合、依存される側が先に実行されていないとエラーになります。ライブラリを使うコードが、ライブラリ本体より先に走ると「未定義」のエラーで止まるのが典型です。
無指定のscriptは書いた順に同期実行されるので順序は守られますが、HTMLの解析を止めるため表示が遅くなりがちです。deferは順序を保ちつつ解析を止めないので、依存関係があるスクリプトには扱いやすい選択肢になります。
asyncは順序保証がないため、依存関係のあるコードには向きません。広告や計測タグのように、他と独立して動くスクリプトに限って使うのが安全です。
症状別チェック表
scriptのdefer/asyncで読み込み順が崩れて動かないは、症状を分けずに直そうとすると原因探しが長引きます。まず「自分だけで起きるのか」「全員で起きるのか」「特定ブラウザだけか」「差し替え後だけか」を切り分けます。
確認順序を固定すると、相対パス、ファイル名、キャッシュ、認証、外部読み込みのどこで止まっているかが見えます。修正後はローカル確認だけで終わらせず、実際の共有URLで再表示して、相手と同じ条件で直ったことを確認します。
- 自分だけ表示されない: キャッシュ、ログイン状態、ブラウザ拡張、端末幅を確認する
- 全員で表示されない: ファイル構成、相対パス、大文字小文字、アップロード漏れを見る
- 一部だけ崩れる: CSS/画像/JSごとに読み込みエラーを分ける
- 差し替え後だけ古い: URL、キャッシュ、更新対象ファイルの取り違えを確認する
実行順を立て直す手順
順番が崩れているときは、まず依存関係を整理してから読み込み方法を選び直すと迷いません。次の順で進めます。
- どのスクリプトがどれに依存しているかを書き出す
- 依存される側(ライブラリ等)を先、使う側を後に並べ替える
- 依存関係があるものはasyncを外し、deferに揃える
- 独立して動くスクリプトだけにasyncを残す
- 再読み込みしてConsoleに未定義エラーが出ないか確認する
DOM操作のタイミングにも注意
順序のほかに、要素がまだ存在しないうちにDOMを操作してnullになるケースもあります。deferはHTMLの解析完了後に実行されるためDOMが揃った状態で動きますが、headに置いた無指定のscriptは要素より先に走るため、対象が見つからずエラーになりがちです。
DOMを触るコードは、deferを使うか、本文の末尾に置くか、読み込み完了を待つイベントの中で実行すると安定します。実行順とDOMの準備状態は別の問題なので、両方そろって初めて意図通りに動きます。
並べ替えたら実環境で再確認する
asyncの順序は環境やネットワーク状況で変わるため、手元で一度動いたからといって安心はできません。回線条件の違う相手の環境でも安定して動くかを、実際の配信で確かめるのが確実です。
ギガサイト便にZIPをドロップすると 〇〇.giga-site.com でCDNのエッジ配信になり、本番に近い読み込み条件で検証できます。同じURLのまま差し替えられるので、読み込み順を直したHTMLを上げ直し、Consoleの未定義エラーが消えるまで反復できます。複数の関係者にQRコードや認証付きURLで配って、それぞれの環境での動作を確認してもらうのも有効です。
よくある質問
deferとasyncはどう使い分ければよいですか
順番が重要で依存関係があるスクリプトはdefer、他と独立して動くスクリプト(計測タグなど)はasyncが向きます。deferは書いた順を保ち、asyncは読み込めた順に実行されます。
asyncを付けると毎回動作が変わるのはなぜですか
asyncは読み込み完了の早い順に実行されるため、ファイルサイズや回線状況で順番が変わります。依存関係のあるコードに使うと、たまたま動いたり止まったりする不安定さの原因になります。
未定義エラーが出ます。どこを直せばよいですか
依存される側が先に実行されていない可能性が高いです。ライブラリ本体を先、それを使うコードを後に並べ、両方をdeferに揃えると順序が保たれます。
要素が見つからないエラーはどう直しますか
DOM操作がHTML解析より先に走っています。deferを使う、本文末尾にscriptを置く、読み込み完了イベントの中で実行する、のいずれかでDOMが揃ってから動くようにしてください。
原因が分からないときはどこから確認すべきですか?
まず自分だけの問題か全員の問題かを分けます。次にシークレットウィンドウ、別ブラウザ、スマホで確認し、ファイル構成・相対パス・キャッシュ・認証設定を順に見ます。