今回はHTMLのページ表示を早めるために、JavaScriptを読み込むときに気をつけるべきポイントについてのお話です。
なんかWebページの表示まで時間がかかるんだけど、フロントエンドで対応できることってないのかしら?
JavaScriptファイルの読み込みはうまく言っているんだけど、DOM操作がうまくいっていない。
このような問題に直面している人にとってはピンポイントで解決される内容になるかと思います。
HTMLのページ描画(レンダリング処理)とJavaScriptファイルの読み込みの流れの解説も行います。
今回の記事を読むことで、上記の問題が起きる原因を仕組みから理解することが出来ます。
今回の記事では次の2点について解説します。
- scriptタグは出来るだけbodyの後ろに置く
- JavaScriptの読み込みの順番を気をつける
それでは、1つ目の内容から見ていきましょう。
目次
scriptタグは出来るだけbodyの後ろに置く
まず1つ目の気をつけるポイントは、JavaScriptファイルを読み込むときはbodyタグ内の一番後ろにscriptタグを配置することです。
ソースコードでいうと次のようなイメージです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>サンプルコード</title> </head> <body> <h1>サンプルコード</h1> <p>scriptタグはbodyの一番最後に置いたほうが良い</p> <!-- ここから下にscriptタグを置く --> <script src="https://code.jquery.com/jquery-1.12.4.min.js"></script> <script src="./common.js"></script> <script src="./main.js"></script> <script src="./control-dom.js"></script> </body> </html> |
上記サンプルコードを見ていただくとわかるかと思いますが、bodyタグの終わりの方(14~17行目)にscriptタグを記述してJavaScriptファイルを読み込んでいます。
headタグ内(3~8行目)にもscriptタグを記述してJavaScriptファイルを読み込むことも可能ですが、bodyタグの後ろの方で読み込むときとどんな違いがあるのでしょうか?
結論から言うとbodyタグの後ろの方でJavaScriptファイルを読み込むことで次のメリットがあります。
- HTMLのレンダリング(描画)が早くなる
- DOMの操作が出来るタイミングになる
HTMLのレンダリング(描画)が早くなる
HTMLはページを表示するためにHTMLコードを上から順番に処理を実行します。
headタグ内でJavaScriptの外部ファイル読み込むときは、JavaScriptファイルの読み込みが完了するまで次の行に処理が進みません。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>サンプルコード</title> <!-- JavaScriptファイル読み込み箇所 --> <script src="https://code.jquery.com/jquery-1.12.4.min.js"></script> <script src="./common.js"></script> <script src="./main.js"></script> <script src="./control-dom.js"></script> </head> <body> <h1>サンプルコード</h1> <p>headタグ内でJavaScriptファイルの読み込みを行うとbodyタグ内まで来るのに時間がかかる</p> </body> </html> |
上記サンプルコードではheadタグ内(9~12行目)で4つのJavaScriptファイル読み込みんでいます。
このときに何が起きているか順番に見ていくと次のようになります。
- 9行目でhttp経由でJQueryを読み込む。
- JQueryの読み込みが完了したら10行目に移動してcommon.jsを読み込む
- common.jsの読み込みが完了したら11行目に移動してmain.jsを読み込む
- main.jsの読み込みが完了したら12行目に移動してcontrol-dom.jsを読み込む
- control-dom.jsの読み込みが完了したらhead内の処理が完了してbodyタグ内の処理に入る。(ページのレンダリング処理)
Webページの表示は出来るだけ早いほうがユーザーに優しいです。
しかし上記の流れでいうと5番目までいって、やっとHTMLのレンダリングが出来るようになります。
そこで、bodyタグの終わりの方にJavaScriptファイルの読み込み処理を移動することで、Webページの表示を先に持ってくることが出来ます。
もう一度bodyタグの終わりの方でJavaScriptを読み込んだサンプルコードを確認してみましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>サンプルコード</title> </head> <body> <h1>サンプルコード</h1> <p>scriptタグはbodyの一番最後に置いたほうが良い</p> <!-- ここから下にscriptタグを置く --> <script src="https://code.jquery.com/jquery-1.12.4.min.js"></script> <script src="./common.js"></script> <script src="./main.js"></script> <script src="./control-dom.js"></script> </body> </html> |
bodyタグの終わりの方にJavaScriptの読み込みを行ったときの処理の流れは次のようになります。
- headタグ内で外部ファイル読み込みはないため、すぐにbodyタグ内の処理に入る(レンダリング処理)
- 11行目のpタグのレンダリングが終わったら14行目でhttp経由でJQueryを読み込む。
- JQueryの読み込みが完了したら15行目に移動してcommon.jsを読み込む
- common.jsの読み込みが完了したら16行目に移動してmain.jsを読み込む
- main.jsの読み込みが完了したら17行目に移動してcontrol-dom.jsを読み込む
上記のコードの場合、ページのレンダリング処理が1番目に移動しました。
このようにJavaScriptの読み込みを行う場所を返るだけでユーザーにとってはWebページの表示が早くなるので、
可能な限りbodyタグの後ろの方でJavaScriptファイルの読み込みを行うようにしましょう。
DOMの操作が出来るタイミングになる
まず、「DOMの操作」をあらためて確認しましょう。
「document.getElementById」や「JQueryの$(‘#id’)」などを使って特定のタグの内容を変更すること。
このDOM操作を行うためには、まず最初にDOMの読み込みが完了していることが前提となります。
そのため、レンダリング処理(ページ描画)が始まる前にJavaScriptでDOM操作を行おうとすると、DOM操作が行えるタイミングではないのでエラーになります。
実際にサンプルコードを使って説明します。今回は説明のためにJavaScriptを外部ファイル読み込みではなくインラインスクリプト形式で実行します。
インラインスクリプトとは、JavaScriptを外部ファイルとして持つのではなく、HTMLの中で直接JavaScriptの処理を記述する書き方。
headタグ内でDOM操作を行った場合(エラー)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>サンプルコード</title> <!-- インラインスクリプトで処理 --> <script> const h1 = document.getElementById('logo'); console.log('h1の内容は : ', h1.innerText); </script> </head> <body> <h1 id="logo">サンプルコード</h1> <p>scriptタグはbodyの一番最後に置いたほうが良い</p> </body> </html> |
headタグ内でDOM操作を行った上記コードの実行結果は次のとおりでエラーになっています。
bodyタグの後ろの方でDOM操作を行った場合(エラー)
それでは、次にbodyタグの後ろの方で同じ処理を行った場合はどうなるのか確認してみましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>サンプルコード</title> </head> <body> <h1 id="logo">サンプルコード</h1> <p>scriptタグはbodyの一番最後に置いたほうが良い</p> <!-- インラインスクリプトで処理 --> <script> const h1 = document.getElementById('logo'); console.log('h1の内容は : ', h1.innerText); </script> </body> </html> |
上記コードの結果は次の通りで、「console.log」を使って指定したDOMの中身のテキストを取得することが出来ています。
「onload」や「JQueryの$(function(){})」などの機能を使ってページの読み込みが完了してから実行されるイベントを使えば、headタグ内でもDOM操作を行うことは出来ます。
(イベントについては以下の「あわせて読みたい」を参照。)
しかし、Webページのレンダリングはheadタグ内の処理が終わってから行われます。
そのため、headタグ内でJavaScriptファイルの読み込みがあれば、JavaScriptの読み込み完了を待つ必要があるのでWebページの表示が遅れます。
まとめ
今回はHTMLのレンダリングのタイミングとJavaScriptのファイル読み込みの関係性について説明しました。
あらためてこの記事で話したことを以下にまとめます。
- JavaScriptファイルの読み込みをbodyタグの後ろの方にすることで、ページの表示が早くなる
- headタグ内でDOM操作を行うとエラーになる
- イベントを使ってheadタグ内でDOM操作を出来るようにしても、ページの表示が遅くなる
Webページの表示が遅いWebサイトにイライラした経験はないでしょうか?
自分の作るページがそうならないようにWebページの表示が早くなるように出来るところから対応していきましょう^^