🚀

HTMLの<script>を書く位置について

2024/06/06に公開

普段HTMLを書かないと忘れていくので備忘録もかねて

scriptタグどこに記載すればよいか問題

HTMLでscriptを記載できる位置がいくつかあり、
どこに書けばよいか分からなくなるのでそれぞれ書く位置と問題点を記載していく

scriptタグを記載できる位置

HTMLドキュメントでは、<script>タグを以下の場所に記載することができる。

  1. <head>タグ内:
index.html
<head>
    <script src="./index.js"></script>
</head>

ここに記載すると、HTMLの解析前にスクリプトが読み込まれて実行される。
bodyでのDOM解析より前に走るため、ページのレンダリングがブロックされることがある。
特に外部リソースが多い場合やスクリプトが重い場合、ページの表示が遅れる原因となる。

  1. <body>タグ内の適切な場所:
  • <body>の最初:
index.html
<body>
    <script src="./index.js"></script>
    <!-- ページのコンテンツ -->
</body>

<body>の最初にスクリプトを配置すると
<head>内に配置した場合と同様に、レンダリングがブロックされる可能性がある。
<head>の時と同じく、スクリプトが重い場合はページの表示が遅れる原因となる。

  • <body>の終わり:
index.html
<body>
    <!-- ページのコンテンツ -->
    <script src="./index.js"></script>
</body>

bodyでのDOM解析より前に走るため、HTMLの解析とページのレンダリングが完了してからスクリプトが実行されることになる。
ページを開いたときに描画が先にされるため、ユーザーから見たときにページ表示速度が早い。

<body>タグの最後尾に書くのが最適なのか?

描画を第一に考えるのであれば、<body>タグの終わりに書くことが推奨されてる。

ただしDOMが描画される前に行いたい処理などがある場合
<head>タグ内で初期化処理を記載した方が、読み込み順序等を気にする必要がなくなるため
あえて<head>に記載する方法も良さそう。

例えば

  • ページ初期化系:ページロード前に特定の初期化を行う必要がある場合。
  • 重要な設定系:ユーザー認証やアクセス制御、グローバル設定の適用など、ページ全体に影響を与えたい処理。
  • スタイルやレイアウトの調整系:ページロード後にレイアウトが崩れるのを防ぐために、事前にスタイルを適用する場合。
    上記のような処理は、<head>タグ内に配置するのが良さそう。

個人的に以前行ってたのは以下みたいな処理
(他にもいろいろやり方はあるはずだが一例として、、、)

index.html
<head>
    <script>
        // 認証状態
        let authenticated = false;
        // 認証関連の初期化処理....
    </script>
    <script src="./script.js"></script>
</head>

気を付けないといけない点として、DOMが解析される前に処理を行っているため
DOM関連の操作はここでは行えない。

<head>タグにスクリプトを記載しつつ描画を先に行いたい

<body>の最後に記載する方法が良いとはいえ、
外部のスクリプトなどは<head>にあった方が何を使用しているか分かりやすかったりする。

HTML5以上であればそんなときに使えるdefer属性がある。
defer属性を使用すると、スクリプトはHTMLの解析が完了する(正確にはDOMContentLoadedイベント直前)まで実行を遅延する。
また、外部スクリプト等の場合ダウンロードが発生するが
ダウンロードもDOMの解析と非同期で処理が行われるため、描画に対するブロッキングが発生しない。

  • 遅延読み込み(defer属性):
index.html
<head>
    <script src="./index.js" defer></script>
</head>

async属性でも同じようなことができるが、
async属性の場合、ダウンロードが非同期になるまでは同じで
スクリプトの実行がダウンロード完了次第になるためHTMLの解析と並行する。
そのため特定の順序でスクリプトを実行する必要がある場合には注意が必要。

async属性とdefer属性の詳しい違いは以下のサイトがかなり詳しく分かりやすく紹介してくれているのでそちら参考。
<script> タグに async / defer を付けた場合のタイミング

Discussion