こんにちはフロントエンドエンジニアのまさにょんです!
今回は、HTML内のscriptタグの位置と実行順序の関係・タイミングの調整方法について解説していきます。
目次
Scriptタグの位置は、どこが最適なのか?
Scriptタグの位置によって、どんな影響があるのか?どこが最適なのか?考えていきましょう。
Scriptタグの基本的な記述位置
基本的にScriptタグの記述位置は、次のどちらかにすべきと言われています。
- head タグ内
- body 終了タグの直前
読み込む順序の違いを理解する
どこが最適なのか考える上でのポイントは、読み込む順序の違いです!
HTMLは「 headタグ => bodyタグ 」と上から順に読み込まれます。
もちろん、JavaScriptもheadタグ内にあるものの方が先に起動します。
ここで気づいていただきたいのは「headタグ内のJavaScript」が起動したときに、HTML構造は存在するのか?
という点です。
答えを言うと「headタグ内のJavaScript」が起動したときに、HTML構造はまだDOMには存在しません。
Web画面上に作られていないのです。
と言うことは、もし「headタグ内のJavaScript」でDOM操作をしようとするとErrorがでてしまうわけです。
なので、HTML構造を操作するDOM操作の記述は「body終了タグ直前の JavaScript」に記載した方がいいと言うことになります。
それでは「headタグ内のJavaScript」なんていらないのでは?
と思うかもしれません。
しかし、そんなことはないです。
外部からのデータ取得やHTML構造の完成前に準備しておきたい処理などを記述するのなら「headタグ内のJavaScript」に記述する方が最適だからです。
どんな処理をしたいのかで、headタグ内 or body終了タグの直前を使い分けましょう!
<html lang="en">
<head>
<script type="text/javascript">
console.log('headタグ内の JavaScript起動🔥');
console.log('Data-Feach(外部からのデータ取得)などHTMLが生成される前に実行したい処理を記述しよう🔥');
</script>
</head>
<body>
<h1>Scriptタグの位置は、どこが最適なのか?</h1>
<h2>Scriptタグの記述位置は、次のどちらか🔥</h2>
<h3>1. head タグ内</h3>
<h3>2. body タグの終了直前</h3>
<script type="text/javascript">
console.log('body 終了タグ直前の JavaScript起動(HTML構造は、作られた後)🔥');
console.log('DOM-操作など、HTMLが必要な処理は、ここに記述しよう🔥');
console.log('HTML構造がすでに読み込まれているので、HTML要素を処理する場合にエラーが起きない');
</script>
</body>
</html>
scriptタグの属性による JavaScript実行タイミングの調整
scriptタグの属性には、JavaScriptの実行タイミングを調整できるものがあるので紹介します。
async属性で非同期処理(バックグラウンドで処理実行)にする
async属性は非同期に対象スクリプトの読み込みと実行をします。
非同期(バックグラウンドで処理を実行)なので、時間のかかる処理などを記述するのに向いています。
<head>
<script async>
console.log('async属性を利用した非同期処理-Script-Tag🔥');
console.log('async属性は非同期に対象スクリプトの読み込みと実行をします。');
console.log('非同期なので処理の完了を待たずに、次の処理に進んでいきます!');
console.log('非同期(バックグラウンドで処理を実行)なので、時間のかかる処理などを記述するのに向いている');
</script>
</head>
defer属性でDOMのレンダリング完了を待つ
defer属性は対象スクリプトの読み込み後、実行はDOMのレンダリング後に行います。
defer は「延期する」という意味の英単語です。
HTML構造の読み込みを完了したら、実行するのが「 defer属性 」と覚えましょう。
<head>
<script defer>
console.log('defer属性を適用した Script-Tag🔥');
console.log('defer は「延期する」という意味の英単語');
console.log('defer属性は対象スクリプトの読み込み後、実行はDOMのレンダリング後に行います。');
console.log('HTMLの構造がすべて読み込み完了したら実行するのが「 defer属性 」');
</script>
</head>
JavaScriptの関数によるJavaScript実行タイミングの調整
JavaScriptの関数によるJavaScriptの実行タイミングの調整は、以前にこちらの記事で紹介しました。
簡単に紹介すると、JavaScriptの実行タイミングを調整できる関数には、次の3つの種類があります。
- scriptタグの該当関数まで到達したらすぐに実行する関数
- HTMLが読み込み完了したら実行する関数
- HTMLや画像など、すべてのデータの読み込みが完了したら実行される関数
このようにJavaScriptには、実行タイミングを調整できる関数があるので、これらで処理のタイミングを決めることができます。
SampleCode全文
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Script-Location-Test🔥</title>
<script type="text/javascript">
console.log('headタグ内の JavaScript起動🔥');
console.log('Data-Feach(外部からのデータ取得)などHTMLが生成される前に実行したい処理を記述しよう🔥');
console.log('-------------------------------- headタグ内の普通の scriptタグ終了🔥 -----------------------------------------');
</script>
<script async>
console.log('async属性を利用した非同期処理-Script-Tag🔥');
console.log('async属性は非同期に対象スクリプトの読み込みと実行をします。');
console.log('非同期なので処理の完了を待たずに、次の処理に進んでいきます!');
console.log('非同期(バックグラウンドで処理を実行)なので、時間のかかる処理などを記述するのに向いている');
console.log('-------------------------------- headタグ内の async-scriptタグ終了🔥 -----------------------------------------');
</script>
<script defer>
console.log('defer属性を適用した Script-Tag🔥');
console.log('defer は「延期する」という意味の英単語');
console.log('defer属性は対象スクリプトの読み込み後、実行はDOMのレンダリング後に行います。');
console.log('HTMLの構造がすべて読み込み完了したら実行するのが「 defer属性 」');
console.log('-------------------------------- headタグ内の defer-scriptタグ終了🔥 -----------------------------------------');
</script>
</head>
<body>
<h1>Scriptタグの位置は、どこが最適なのか?</h1>
<h2>Scriptタグの記述位置は、次のどちらか🔥</h2>
<h3>1. head タグ内</h3>
<h3>2. body タグの終了直前</h3>
<h2>[ Point ]</h2>
<h3>1. ファイルを読み込むタイミングの違いを理解する🔥</h3>
<h3>2. ブラウザは、HTMLファイルを上から順に読み込んでいきます。</h3>
<p>「 headタグ => bodyタグ 」と上から順に読み込まれます。</p>
<p>JavaScriptもheadタグ内にあるものの方が先に起動します。</p>
<h3>3. どんな処理をしたいのかで、headタグ内 or bodyタグの終了直前を使い分けましょう!</h3>
<h2>HTMLタグ属性による JavaScript実行タイミングの調整</h2>
<h3>1. async属性の活用</h3>
<p>async属性は非同期に対象スクリプトの読み込みと実行をします。</p>
<h3>2. defer属性の活用</h3>
<p>defer属性は対象スクリプトの読み込み後、実行はDOMのレンダリング後に行います。</p>
<h2>JavaScriptの関数によるJavaScript実行タイミングの調整🔥</h2>
<h3>
以前にこちらの記事で紹介しました!
<a href="https://masanyon.com/javascript-page-load-run-timing/" target="_blank" style="text-decoration: none;" >
ページ(HTML)の表示・読み込み(load)時に実行されるJavaScriptのイベントまとめ
</a>
<br><br>
1. scriptタグの該当関数まで到達したらすぐに実行する関数
<br><br>
2. HTMLが読み込み完了したら実行する関数
<br><br>
3. HTMLや画像など、すべてのデータの読み込みが完了したら実行される関数
<br><br>
などのJavaScriptの関数があるので、これらでタイミングを調整できます。
</h3>
<h2>参考・引用</h2>
<h3>
<ol>
<li>
<a href="https://codeaid.jp/js-load/" target="_blank">JavaScriptを書く場所や読み込む場所はどこがいいのか?</a>
</li>
<li>
<a href="https://webukatu.com/wordpress/blog/39711/" target="_blank">JavaScriptはheadとbodyのどちらで読み込むのが最適なのか?</a>
</li>
</ol>
</h3>
<script type="text/javascript">
console.log('body 終了タグ直前の JavaScript起動(HTML構造は、作られた後)🔥');
console.log('DOM-操作など、HTMLが必要な処理は、ここに記述しよう🔥');
console.log('HTML構造がすでに読み込まれているので、HTML要素を処理する場合にエラーが起きない');
console.log('-------------------------------- body終了タグ直前の scriptタグ終了🔥 -----------------------------------------');
</script>
</body>
</html>
JavaScript書籍 Ver. 中級-上級者向け
JavaScript書籍 Ver. 初級者向け
Twitterやってます!Follow Me!
神聖グンマー帝国の逆襲🔥
神聖グンマー帝国の科学は、世界一ぃぃぃぃぃぃ!!!!!