WEB

[JavaScript]なぜ<script>は<body>の最後に書くのか

WEB
この記事は約4分で読めます。

はじめに

昨今HTMLにおいて、JavaScriptを用いる機会が多いですが
何となく正しいと思っていても、書き方によってはエラーになってしまう例をご紹介します。

こんな話がありました

JavaScriptに触れて間もない頃、一緒に勉強していた人に以下のような質問を受けました。

Aさん「scriptタグの記述する位置によって、エラーになったりならなかったりするんですが」

成功例:<body>の後ろに記述した場合

※どのような記述か正確には覚えていないため、完全感覚イメージです

test.html

<html>
  <head>
  </head>
  <body>
    <div>
      1番目<input type="text" id="calc1" value=10>
    </div>
    <div>
      2番目<input type="text" id="calc2" value=5>
    </div>
  </body>
  <script type="text/javascript" src="test.js" charset="UTF-8"></script>
</html>

test.js

// 1番目の要素を取得
let calc1 = parseInt(document.getElementById('calc1').value);
console.log('1番目の値は:' + calc1);
console.log('1番目の型は:' + typeof(calc1));

// 2番目の要素を取得
let calc2 = parseInt(document.getElementById('calc2').value);
console.log('2番目の値は:' + calc2);
console.log('2番目の型は:' + typeof(calc2));

// 引き算
console.log(calc1 - calc2);
// 割り算
console.log(calc1 / calc2);
// 掛け算
console.log(calc1 * calc2);
// 足し算
console.log(calc1 + calc2);

失敗例:<body>より前に記述した場合

test.html

<html>
  <head>
    <script type="text/javascript" src="test.js" charset="UTF-8"></script>
  </head>
  <body>
    <div>
      1番目<input type="text" id="calc1" value=10>
    </div>
    <div>
      2番目<input type="text" id="calc2" value=5>
    </div>
  </body>
</html>

自分「ほんまや…」
※なお、エラー内容は「’value’が null なのですが」と読み取れます

何故なのか調べてみた

色々調べてみて、今回コンソールにエラーが出ているHTMLでは
以下のような順序で画面が表示されている事がわかりました。


①リソースファイル(HTML)の取得
②取得したファイルの解析(HTMLの一番上から順々に解析が行われる)
┗scriptタグがあった場合、解析を中断して記述されている内容が実行されるのを待つ
③DOMツリー出来上がり
④レンダリング
⑤レンダリング結果の描画


どうやら、上に赤字で表記した部分が今回のエラー原因となっているようです。
例で記述している js では DOM の操作がありますが
冒頭の失敗例の記述だと操作しようとしている要素が解析される前に、要素に対しての処理が行われる
という状況になってしまい、null になってしまっていたわけですね。

最後に

何となく正しいと思っていても、書き方によってはエラーになってしまう例をご紹介しました。

スクリプトの実行タイミングを変更する事でエラーとならない記法もありますので、
また機会があればご紹介したいと思います。

参考資料

ブラウザレンダリングを理解するため簡単にまとめてみた