[解決済み] HTMLマークアップのどこに<script>タグを記述すればよいですか?
質問
HTML文書にJavaScriptを埋め込むとき、どこに
<script>
タグと含まれるJavaScriptについて教えてください。私は、これらを
<head>
セクションの冒頭に配置します。
<body>
セクションでは、ページが完全にレンダリングされる前に JavaScript をパースする必要があるため、これも好ましくありません (あるいはそのようなもの)。これでは
終了
の
<body>
セクションの論理的な場所として
<script>
タグを使用します。
では、どこで
は
を置くのに適した場所です。
<script>
タグは?
(この質問は
この質問
その中で、JavaScript の関数呼び出しを
<a>
タグから
<script>
タグを使用します。具体的にはjQueryを使用していますが、より一般的な回答も適切です)。
どのように解決するのですか?
以下は、ブラウザでWebサイトを読み込む際に
<script>
というタグがあります。
- HTMLページを取得する(例. index.html )
- HTMLのパースを開始する
-
パーサが遭遇したのは
<script>
タグが外部スクリプトファイルを参照している。 - ブラウザはスクリプトファイルを要求します。一方、パーサーはページ上の他のHTMLをブロックし、パースを停止します。
- しばらくすると、スクリプトがダウンロードされ、その後実行されます。
- パーサーは、HTML ドキュメントの残りの部分の解析を続行します。
ステップ#4は、悪いユーザーエクスペリエンスを引き起こします。ウェブサイトは基本的に、すべてのスクリプトをダウンロードするまで読み込みを停止します。ユーザーが嫌がることといえば、ウェブサイトが読み込まれるのを待つことです。
なぜこのようなことが起こるのでしょうか?
どのスクリプトも、独自のHTMLを
document.write()
やその他の DOM 操作を行うことができます。これは、パーサーがドキュメントの残りの部分を安全に解析する前に、スクリプトがダウンロードされ実行されるまで待機しなければならないことを意味します。結局のところ、スクリプトは
は
は、文書内に独自のHTMLを挿入しています。
しかし、ほとんどの JavaScript 開発者は、もはや DOM 一方 を使用します。その代わりに、彼らはドキュメントが読み込まれるまで待ってから修正します。例えば
<!-- index.html -->
<html>
<head>
<title>My Page</title>
<script src="my-script.js"></script>
</head>
<body>
<div id="user-greeting">Welcome back, user</div>
</body>
</html>
JavaScriptです。
// my-script.js
document.addEventListener("DOMContentLoaded", function() {
// this function runs when the DOM is ready, i.e. when the document has been parsed
document.getElementById("user-greeting").textContent = "Welcome back, Bart";
});
ブラウザが知らないので my-script.js がダウンロードされ、実行されるまでドキュメントを変更することはないため、パーサーはパースを停止します。
時代遅れの推奨
この問題を解決するための昔のアプローチは
<script>
タグの下にある
<body>
こうすることで、パーサーが最後までブロックされることがなくなるからです。
この方法には、ドキュメント全体の解析が完了するまで、ブラウザがスクリプトのダウンロードを開始できないという問題があります。大きなスクリプトやスタイルシートを含む大規模なウェブサイトでは、できるだけ早くスクリプトをダウンロードできることが、パフォーマンスにとって非常に重要です。もしあなたのウェブサイトが2秒以内にロードされなければ、人々は他のウェブサイトに移動してしまうでしょう。
最適なソリューションでは、ブラウザはスクリプトのダウンロードをできるだけ早く開始し、同時にドキュメントの残りの部分を解析します。
現代のアプローチ
現在、ブラウザは
async
と
defer
属性をスクリプトに追加します。これらの属性は、スクリプトがダウンロードされている間、パージングを続けても安全であることをブラウザに知らせます。
非同期
<script src="path/to/script1.js" async></script>
<script src="path/to/script2.js" async></script>
async属性を持つスクリプトは、非同期で実行されます。つまり、スクリプトはダウンロードされるとすぐに実行され、その間にブラウザがブロックされることはありません。 これは、スクリプト2がスクリプト1より先にダウンロードされ、実行される可能性があることを意味します。
によると http://caniuse.com/#feat=script-async 全ブラウザの97.78%が対応しています。
延期
<script src="path/to/script1.js" defer></script>
<script src="path/to/script2.js" defer></script>
defer属性を持つスクリプトは、順番に実行されます(つまり、最初にスクリプト1、次にスクリプト2)。これもブラウザをブロックすることはありません。
非同期スクリプトとは異なり、deferスクリプトはドキュメント全体が読み込まれた後にのみ実行されます。
によると http://caniuse.com/#feat=script-defer 全ブラウザの 97.79% が対応しています。98.06%は少なくとも部分的にサポートしています。
ブラウザの互換性に関する重要な注意事項:Internet Explorer 9 以前のバージョンでは、状況によっては遅延されたスクリプトが順番通りに実行されないことがあります。これらのブラウザをサポートする必要がある場合は、以下を参照してください。 これ を最初にお読みください。
(もっと詳しく知りたい、非同期、遅延、通常のスクリプトの違いについて本当に役に立つ視覚的な表現を見たい場合は、この回答の参考文献セクションにある最初の2つのリンクをチェックしてください)
まとめ
現在の最先端は、スクリプトを
<head>
タグを使用し
async
または
defer
属性を使用します。これにより、ブラウザをブロックすることなく、あなたのスクリプトを早急にダウンロードすることができます。
良い点は、これらの属性をサポートしていない2%のブラウザでもウェブサイトが正しく読み込まれ、残りの98%のブラウザが高速化されることです。
参考文献
関連
-
Vueの要素ツリーコントロールに破線を追加する説明
-
jsを使った簡単な照明スイッチのコード
-
WeChatアプレット用ユニアプリによるグローバルシェアリング
-
jQueryのコピーオブジェクトの説明
-
Vueにシンプルなメモ帳機能を実装
-
[解決済み】(Google Map API) Geocodeは以下の理由で成功しませんでした。REQUEST_DENIED
-
[解決済み] 文字列からHTMLタグを削除する
-
[解決済み] HTMLアンカーは'name'と'id'のどちらで作成するのが良いですか?
-
[解決済み] label要素の中にinput要素を入れるべきですか?
-
[解決済み】一部のHTMLタグに任意のデータを格納する方法
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
要素ツリー制御によるvueTreeテーブル
-
JavaScriptにおけるマクロタスクとミクロタスクの詳細
-
jsを使った簡単な照明スイッチのコード
-
Vueのクラススタイルの使い方の詳細
-
[解決済み】Node.js Error: Cannot find module express
-
[解決済み】TypeErrorの解決方法。未定義またはヌルをオブジェクトに変換できない
-
[解決済み】JavaScriptでインラインIF文の書き方は?
-
[解決済み】 `string.split is not a function` というエラーの原因は何ですか?
-
[解決済み】リクエストに失敗していないのに、「TypeError: failed to fetch」が表示される。
-
フロントエンド null のプロパティ 'disabled' を読み取れない 問題が解決された