どうもこんにちは。
先にお伝えしますと、この質問は技術的興味から来た質問です。
まず、HTMLのコードで以下の書き方をよく見かけます。
HTML
1<!doctype html> 2<html> 3<head> 4 <link rel="stylesheet" href="http://example.com/"> 5 <meta charset="utf-8"> 6 <title></title> 7</head> 8<body> 9<script src="http://example.com/"></script> 10</body> 11</html>
このコードでscriptタグをbodyタグの下に書いている理由をご教授していただきたいということが今回の質問内容です。
稚拙な質問で恐縮ですが、よろしくおねがいします。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答8件
0
scriptタグの記述場所は別にどこでも構わないのですが、bodyタグの終端に記述する理由は以下のような理由があるのではないかと思います。
- javascriptファイルを読み込んでいる間は、HTMLファイルを読み込まないため、ページのレンダリングを行わせてからjavascriptファイルを読み込むことで表示速度を早くする。
- CSSはheadタグ中に、javascriptはbodyタグの下にまとめて記述することでわかりやすくなる。
ただし、HTMLが解析される前に実行されるべきjavascriptファイルなどはheadタグ内に記述するべきだと思います。
headタグ内にscriptタグを置いたときには、javascriptファイルが最初に読み込まれるので、そのjavascriptファイルのサイズが巨大だった場合、ページの表示に時間がかかることになります。その解決策として、async属性という非同期的にjavascriptファイルを読み込むことができるようになる属性を使います。ただし、非同期的にjavascriptファイルを読み込むということは、ファイルが複数ある場合にどれが最初に読み込まれるかわからないということです。なので、もしもA.js
とB.js
というファイルがあって、絶対にA.js
から先に読み込む必要があったとしても、async属性を使うとB.js
から読み込まれてしまうことがあります。また、**一部ブラウザがこの属性に対応していない**ので注意する必要があります。
投稿2017/02/26 01:57
総合スコア14731
0
scriptタグをbodyタグの下に書いている理由
SEOの観点です。
大前提として、scriptタグをHTML内に挿入すると、
そのscriptを定義すると、一度その時点でページのレンダリングはストップします。
srcが定義されているならファイルをダウンロードし、全ての行の実行が完了してからページのレンダリングを再開します。
HTMLとCSSで人間が理解出来るページがほぼ大多数を占めています。
なので、最初に見る画面としてはJavaScriptは存在する必要はありません。
3秒以内にページが表示されないとユーザーの4割は直帰してしまうという統計データがあるそうです。
「SEO 3秒」等で調べてみてください。
要するにユーザーに見せる画面は早ければ速いほどよいという考え方です。
その辺の経緯から、様々なノウハウが蓄積されていきました。
- JavaScriptは慎ましく
- 初動のレンダリングにJavaScriptは関係ないんだから下に書け
これはGoogleのサーチエンジンのコンセプトにも取り入れられており、
上記の条件に準拠したページはSEOとして順位にプラスの評価値がつきます。
この仕組みを利用する手段もあります。
例えばサイト改善の手法の1つにA/Bテストがあります。
ランダムに2~3パターンのページをどれを表示するかを決定し、
どのページに割り振られたユーザーがそのサイトに好意的だったかを調べてサイト改善の材料にします。
このA/BテストのOptimizelyでは、
Headタグ内にスクリプトを設置すると、読み込みが終わるまでページのレンダリングを行わないという仕様を逆手に取り、
あえてHeadタグ内にOptimizelyのタグを埋め込み、対象ページの選定やらページの書き換え内容を宣言した後に、ページをレンダリングさせます。
投稿2017/02/26 03:37
総合スコア21194
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
(通常ではありませんが)エレメントのロードが終わってからスクリプトが実行されるからです。
例えば
javascript
1var btn = document.getElementById('btn');
というコードを書いた<script>を<head>内に書いた場合は、btnが取得できません。(window.onloadやwindow.addEventListener('DOMContentLoaded')などイベント後は取得できる)
ただ、<head>に書いても<script defer src="hoge.js">としてdeferロードを設定した場合もエレメントのロードが終わってから実行されます。
投稿2017/02/26 01:56
編集2017/02/26 02:30総合スコア4269
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
すでに書かれていますが、script タグ自体、header タグの中、body タグの中のどこに書いても構いません。
Javascript が読み込まれている間「HTMLが読み込まれない」のではなく「レンダリングがブロックされる = script タグ以降が表示されない」というのが正しいですね。
なので、表示された後に実行されてよい script は、邪魔にならない場所に書くのが表示速度の面からはベターということになります。ページの要素の最後に書く、ということですね。
defer 属性や async 属性を与えることで、レンダリングのブロックを防ぐことは可能ですが、ブラウザによる差異があったり、読み込まれる順番が重要だったりする場合があるので使用されなかったりします。
async で非同期読込にした場合、Jquery 本体より、プラグインのほうが先に解釈されたりするとまずかったりする場合がありますね。
defer だと、ページの読み込みが完了してから script が解釈されますが、ブラウザによっては対応してなかったりします。
投稿2017/02/28 04:45
総合スコア44
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
仕様の話をきちんとするか、推奨される実装の話をするか、多くの実装の話をするのかで、答えが異なってきます。正確に言うと、「どこまできちんと言うか」が異なってきます。私も仕様書を読み込んでいるわけではないので、間違っているところがあるかもしれません。
きちんと書くように…と言いながら、私も、一部端折りながら書いていますし、JavaScript はほとんど扱わないので、間違っているところもあるかもしれません。
sysyz さんの回答が、技術的に正しく、まとまっていると思います。
動作理解の把握のための比較的質の良い文献が、JavaScriptの記入場所…タグ内の記述の言及があるので参考に、JavaScriptの記述場所まとめパターンの列挙、JavaScriptの読み込みにおける非同期スクリプト注入の悪影響, 旧石器時代のJavaScriptを書いてる各位に告ぐ、現代的なJavaScript超入門 Section1 ~すぐにでも現代っぽく出来るワンポイントまとめ~ あたりでしょうか。
async defer に関連しては、async/defer 属性と DOM 構築 で体感できます。scriptのdefer/asyncを理解し、ページの高速化方法を探る、サイトに適したリソース配置とasync/defer完全マスター – レンダリング優先のグッド・プラクティス、document.writeを使った遅いブログパーツ(例えばzenback)を非同期化してサイトを高速表示する方法 が良くまとまっています。ぜひ読んでください。
本来は記述位置に依存する
まず
- script タグ は、そのタグがある位置によって(HTML ソースに与える)実行結果が異なる
ことは知っておかなければなりません。
document_write.js
として
JavaScript
1document.write("document write!");
があった場合、
html
1<!doctype html> 2<html> 3<head> 4 <meta charset="utf-8"> 5 <title></title> 6</head> 7<body> 8<script src="document_write.js"></script> 9ABC 10<script src="document_write.js"></script> 11</body> 12</html>
は
text
1document write! ABC document write!
という出力になります。2つの "document write!" は script タグの位置に依存しています。つまり、どこに書いても良いと端的に述べてしまうのは大きな誤りなのです。
ただ、現在は document.write は非推奨になっています。「問題がある」のです。
記述位置に依存しないスクリプトが求められる
記述位置に依存するということが分かると(いなくても生じる問題もありますが)、次の問題が生じます。
- script タグの JavaScript が実行されたあとでないと、「正しい」ドキュメントが得られない
例えば、document.write("<div class='script'>");
とあるのと、HTML 文書に <div class='script'>
があるのとは同じレンダリング結果にならないとおかしいですね。スクリプト実行後は再度、HTML ソース全体の解析をしなければならなくなります。
これが、JavaScriptの記述場所まとめのいう、「HTMLのレンダリング前に実行する必要があ」るということです。
このような処理が多いと問題が大きいので、innerHTML
や insertAdjacentHTML
他、「ブラウザが把握している HTML の構造(DOM) に手を入れるスクリプト」を「DOM が準備できた後に」実行することが増えてきました。「旧石器時代の~」に載っているようなことです。
document.getElementById("text");
を使ってあげれば「場所の指定」を「HTML ソース上の id」で指定できるので、特定の場所に特定の記述をさせることが可能になります。
その他
body タグの最後や head タグ内の最後に書く利点・理由
あとは、他の方の記述の方が分かりやすいし、詳しいでしょう。
「記述位置に依存しない」のであれば、「いつ・どのように」実行されても良いでしょう。ここで、ブラウザの HTML ソースの解釈を邪魔せず、できるだけ早くページの概況を表示させるため
- body タグの最後
に書く選択肢が生まれてきます。一方で、head 内にある利点もあるのです。
- (私は詳しくないが) HTMLが解析される前に実行されるべきjavascriptファイル がある…そうです
- HTML ソース内の早い段階に現れるため、ブラウザは早く取得できる…body 末尾にあると、ソースを全部読み終えないと、script タグの外部ソースがあることに気づかないという問題があります。必要なスクリプトの実行開始がどんどん遅れてしまいます。
- ライブラリなど、ソースファイル間には依存関係があることがある…jquery なんかはその例なのでしょうか?これは、「先に」書く必要があるため、head 内に入れておきます。
といった具合です。もう少しコントロールしたいですよね。
defer, async によるロード
defer ありでは
- HTML と並行して、非同期でロード
- レンダリング後に同期的に実行
されます。head タグ内に書く「ブラウザは早く取得できる」メリットは活かしながら、body タグ最後にあるような、「あとで実行」を実現できるわけです。
また、「『DOM が準備された後に実行するコード』を登録するコードを実行」するのは、DOM が準備される前でも良いはずです。async ありでは
- レンダリングと並行して非同期で、ロード完了次第実行
実行されます。
ということで、document.write
は弊害が大きいため、避けられるようになり、結果として、「どこに script タグがあっても動作する」プログラムが求められてきました。文法上は、script タグは body 内でなければならない、ということはありません。
一方で、ソースコード間の依存性がある場合、「読み込むソースの順序」は動作に影響を与えます。記述が「どこでも構わない」ということはありませんから、挙動を把握して記述するようにされてください。
投稿2017/03/01 03:54
総合スコア1111
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
すんごいざっぱな私の認識
大前提
インタプリタ言語なので、上から順番に読み込まれる。
前提
header部分で共通用のjsファイルが読み込まれた後以降なら、どこに書いてもいい。
※読み込み順の依存関係が関係してくる問題です。
実装
SEOタグなら、上部近辺にまとめて書いておくと探しやすくていい。
新規に追加するスクリプトなら一番下に書いて、「自分の実装で影響する範囲を特定しやすく」しておく。
※一番最後にすることで、前のスクリプトに迷惑かけないようにする狙いもあり。
jsエラー出ると、以降の処理が全部とまるので、意外と一番最後に書くの大事です・・・。
投稿2017/02/27 05:32
総合スコア278
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。