こんにちは!Web制作やJavaScriptの勉強、毎日お疲れ様です。
画面に文字や画像を表示させるためにHTMLを書いて、動きをつけるためにJavaScriptを読み込ませる……。最初は「よし、動いた!」と感動するのですが、少し慣れてくるとこんな壁にぶつかりませんか?
「あれ? なんかページが表示される瞬間に、画面がカクついたり、真っ白な時間が長かったりするぞ……?」
そうなんです。私たちが何気なく書いている `` と書いたとしましょう。
ブラウザが上から順にHTMLを読んでいって、このタグに出会った瞬間、ブラウザは「うわっ、大変だ!JavaScriptをダウンロードして、今すぐ実行しなきゃ!」と、それまでの作業をピタッと止めてしまいます。
レストランの例えで言うなら、料理人がスープを作っている途中で、突然配送員が「重要なお知らせです!」と飛び込んでききて、料理人がその場でそれを読まされるようなものです。配送員が読み終わるまで、スープ作りは完全にストップしてしまいます。
これが、HTMLのパース(解析)がブロックされる瞬間です。JavaScriptが大きければ大きいほど、ユーザーの画面には「真っ白な画面」が長く映し出されることになり、「このサイト、重いな……」と離脱されてしまう原因になるのです。
「じゃあ、どうすればいいの!?」ですよね。
その救世主こそが、今回主役の `defer` と `async` なんです。
---
2. `defer`:お行儀よく「後でまとめて読む」お利口さん
まずは `defer`(ディファー=遅延させる) からご紹介します。
`defer` は、JavaScriptの読み込みを裏側でこっそり進めつつ、「HTMLの解析(お仕事)がぜーんぶ終わってから、最後に実行してね」とブラウザにお願いする属性です。
日常の例え:届いた荷物は最後に開封する
オンラインショッピングで次々と荷物(HTMLのパーツ)が届いている最中に、わざわざ作業を止めてダンボールをカッターで開けて中身を確認したりしませんよね?
まずは届いた荷物を部屋の隅にどんどん積み上げて(裏側でスクリプトをダウンロードして)、家全体の片付け(HTMLのパース)が終わったあとに、「さて、中身を開けようか」と一気に開封する(スクリプトを実行する)。これが `defer` の動きです。
ここが嬉しいポイント:
- HTMLのパースを邪魔しないので、画面の表示速度(体感速度)がグッと上がります。
- 複数の `defer` 付きスクリプトがある場合、書いた順番通りに実行されるため、ライブラリとその依存関係があるコード(例:jQueryを先に読み込んで、その後にプラグインを動かすなど)でも安心して使えます。
迷ったら、とりあえずスクリプトは `defer` をつけておけば大きな失敗はありません。「困ったときの優等生」と覚えておいてくださいね。
---
3. `async`:マイペースに「準備ができたら即実行」の自由人
続いて `async`(エイシンク=非同期) です。
`async` も `defer` と同じように、裏側でJavaScriptをダウンロードしてくれますが、決定的な違いがあります。それは、「ダウンロードが終わった瞬間、HTMLの解析を無理やり止めてでも、その場で実行する」というマイペースさです。
日常の例え:郵便受けに届いた「緊急の回覧板」
家事をしている最中に郵便受けに「回覧板」が入っているのを見つけたとします。
`async` は、「あ、回覧板だ。今やっている掃除をちょっと中断して、その場で内容を読み上げちゃうね!」という動きです。
どんなときに使うの?
他のHTMLの要素や、他のJavaScriptに依存しない、完全に独立したスクリプトに向いています。
代表例が「アクセス解析ツール(Google Analyticsなど)」や「広告タグ」です。これらは「ページの他の部分がどうなっていようと、とにかく早く読み込んで動いてくれればいい」ものなので、`async` が最適解になります。
逆に、DOM要素(ボタンやテキスト)を操作する自作のJavaScriptに `async` をつけてしまうと、「まだHTMLのパーツが準備できてないよ!」というタイミングでスクリプトが暴走してエラー(`Uncaught TypeError` など)を引き起こすことがあるので注意してくださいね。
「あ、エラーが出ちゃった!」というときは、`async` を `defer` に変えてみるとスッと解決することがよくありますよ。
---
4. 現代の標準! `type="module"` のスマートな秘密
さて、近年のモダンなWeb開発では、ES Modules(ESM)という仕組みを使って、JavaScriptファイルを `import` / `export` で分割して書くのが当たり前になりました。
ここで書く、`type="module"` です。
実はこの `type="module"`、標準で `defer` と全く同じ遅延実行の性質 を持っています。
つまり、ブラウザは自動的に「お、モジュールだな。じゃあHTMLの解析を止めずに、裏側でダウンロードして、解析が終わってから実行しよう」と判断してくれます。わざわざ `defer` と書き添える必要はありません(書いても動きますが、重複します)。
モジュールがレンダリングに与える影響
ES Modulesは、他のファイルを `import` する依存関係のツリーをブラウザが事前にしっかりと組み立ててから実行します。そのため、安全性が高く、スコープ(変数の有効範囲)も綺麗に保たれます。
実務においては、特別な理由がない限り、現代のフロントエンド開発ではJavaScriptをモジュールとして読み込み、ブラウザのレンダリングパイプラインをスムーズに保つのが王道のスタイルになっています。
---
まとめ:今日から使える「scriptタグの選び方」
ここまで、ブラウザの頑張りと、それを助ける属性たちを見てきました。最後に、実務で迷ったときにパッと見返せる「選び方のチートシート」を置いておきますね。
1. 基本のキ(迷ったらこれ)
- 自作のアプリケ―ションコードやライブラリ群
- 👉 `` (または `type="module"`)
2. 独立した外部ツール(解析・広告など)
- 他の要素に依存せず、最速で読み込ませたいもの
- 👉 ``
3. どうしてもHTMLのパースをその場で止めたい場合(ごく稀)
- スクリプトの読み込み順が絶対で、かつHTMLの構築と完全に同期させたい古い仕組みなど
- 👉 属性なし( `` ) ※ただし現代のWeb制作ではほぼ使いません。
Webブラウザは、私たちが書いたコードを文句も言えず、一生懸命、かつ賢く解釈して画面を描き出そうとしています。そのブラウザの性質をちょっとだけ理解して、適切な手助け(属性の付与)をしてあげることで、ユーザーにとって「サクサク動く、心地よいWebサイト」が作れるようになります。
もしコードを書いていて「あれ、動かないな」「画面が変だな」と思ったら、今日のこの記事を思い出してみてください。「あ、ブラウザが処理の順番で困ってるのかもな」と優しく原因を探れるはずです。
あなたのWeb開発の旅が、もっと楽しく、ワクワクするものでありますように!一緒に一歩ずつ進んでいきましょうね。

コメント