トラブルシュート

scriptのdefer/asyncで読み込み順が崩れて動かないときの対処

複数のJSを読み込んでいて、ライブラリより先に自分のコードが走ってエラーになる。これはdeferやasyncの指定によって実行順が変わったことが原因です。この記事では、それぞれの挙動の違いと、依存関係を壊さない並べ方の見直し手順をまとめます。

defer・async・無指定で実行順が変わる

scriptタグには大きく3つの読み込み方があります。無指定なら見つけた場所でその場で実行、deferならHTMLの解析を止めずに後でまとめて書いた順に実行、asyncなら読み込めたものから順不同で即実行です。この違いを知らないと、書いた順に動くつもりが裏切られます。

特にasyncは読み込み完了の早い順に実行されるため、ファイルサイズやネットワーク状況で順番が毎回変わります。依存関係があるスクリプトにasyncを使うと、たまたま動いたり動かなかったりという不安定さの原因になります。

依存関係があるときに壊れる仕組み

あるスクリプトが別のスクリプトの定義した関数や変数に依存している場合、依存される側が先に実行されていないとエラーになります。ライブラリを使うコードが、ライブラリ本体より先に走ると「未定義」のエラーで止まるのが典型です。

無指定のscriptは書いた順に同期実行されるので順序は守られますが、HTMLの解析を止めるため表示が遅くなりがちです。deferは順序を保ちつつ解析を止めないので、依存関係があるスクリプトには扱いやすい選択肢になります。

asyncは順序保証がないため、依存関係のあるコードには向きません。広告や計測タグのように、他と独立して動くスクリプトに限って使うのが安全です。

症状別チェック表

scriptのdefer/asyncで読み込み順が崩れて動かないは、症状を分けずに直そうとすると原因探しが長引きます。まず「自分だけで起きるのか」「全員で起きるのか」「特定ブラウザだけか」「差し替え後だけか」を切り分けます。

確認順序を固定すると、相対パス、ファイル名、キャッシュ、認証、外部読み込みのどこで止まっているかが見えます。修正後はローカル確認だけで終わらせず、実際の共有URLで再表示して、相手と同じ条件で直ったことを確認します。

  • 自分だけ表示されない: キャッシュ、ログイン状態、ブラウザ拡張、端末幅を確認する
  • 全員で表示されない: ファイル構成、相対パス、大文字小文字、アップロード漏れを見る
  • 一部だけ崩れる: CSS/画像/JSごとに読み込みエラーを分ける
  • 差し替え後だけ古い: URL、キャッシュ、更新対象ファイルの取り違えを確認する

実行順を立て直す手順

順番が崩れているときは、まず依存関係を整理してから読み込み方法を選び直すと迷いません。次の順で進めます。

  1. どのスクリプトがどれに依存しているかを書き出す
  2. 依存される側(ライブラリ等)を先、使う側を後に並べ替える
  3. 依存関係があるものはasyncを外し、deferに揃える
  4. 独立して動くスクリプトだけにasyncを残す
  5. 再読み込みして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が揃ってから動くようにしてください。

原因が分からないときはどこから確認すべきですか?

まず自分だけの問題か全員の問題かを分けます。次にシークレットウィンドウ、別ブラウザ、スマホで確認し、ファイル構成・相対パス・キャッシュ・認証設定を順に見ます。

関連記事

トラブルシュート

Bootstrapのグリッドやコンポーネントが崩れるときの対処

Bootstrapでカラムが揃わない、モーダルやタブが反応しないというトラブルに悩む開発者向け。読み込み順やHTML構造の崩れ、バージョン間の仕様変更が原因かどうかを素早く切り分けられます。

5分で読める
トラブルシュート

type="module"のJSが読み込めない・CORSで止まるときの対処

type=moduleにした瞬間にJSが読み込めなくなってCORSエラーに悩んでいる開発者向け。ESモジュール特有の読み込みルールが厳しい理由と、ローカルと公開環境の違いを踏まえたエラーの切り分け・解消手順をわかりやすく整理しています。

5分で読める
トラブルシュート

公開後にJavaScriptが動かないときの原因と直し方

ローカルでは動いていたボタンやアニメーションが公開後に反応しなくなった方向け。JavaScriptが止まる主な原因をファイルパスや読み込み順の観点で切り分け、自分で直せるかどうかを判断できます。

5分で読める
トラブルシュート

公開後に動画が再生されないときの対処

デモページや資料に埋め込んだ動画が公開後に再生されなくなった方向け。動画ファイルの添付漏れ・パスのズレ・ブラウザの自動再生制限を症状ごとに切り分け、自分でできる確認と対処を把握できます。

4分で読める
トラブルシュート

公開したHTMLのフォームが送信できないときの対処

問い合わせフォームやアンケートの送信ボタンが押せない・エラーになる方向け。静的ファイル公開ではフォームの動作に制約がある理由を理解し、外部サービス連携などの現実的な解決策を選べるようになります。

5分で読める
トラブルシュート

iframeが表示されないときの原因と対処

地図や外部コンテンツをiframeで埋め込んだのに公開後に枠が空白になった方向け。表示許可・HTTPSとHTTPの混在・相対パスのズレを症状ごとに切り分け、適切な対処を選べるようになります。

4分で読める
「トラブルシュート」の記事をもっと見る →