JavaScriptの読み込みを最適化してページの表示速度を高速化する6つの方法

[対象: 中〜上級]

僕のブログではてブ数がいちばん多いのはウェブページを高速化するTIPSを解説した記事です(まだ読んでない人はぜひ読んでください!)。

その記事では高速化全般を扱っていましたが、今日の記事ではJavaScriptに的を絞って表示速度をスピードアップできる施策を6つ紹介します。

もともとはSearch Engine PeopleブログのOptimizing JavaScript for Better Web Performanceで説明されていたものです。

記事作者のJoydeep Deb(ジョイディープ・デブ)氏に僕のブログでの転載許可をもらえました (Thanks, Joydeep!)。

逐一の翻訳ではなく、書かれている内容をもとに僕の言葉で解説していきます。

1. HTTPリクエスト削減のためにJavaScriptファイルを1つに統合する

ウェブページの表示を高速化する秘訣の1つは、HTTPリクエストの数を減らすことです(1枚のウェブページであっても、HTMLファイル本体や画像、スクリプトなどをダウンロードするためにウェブサーバーとブラウザはバックグラウンドで何回も何回もやり取りしている)。

HTTPリクエストの数を減らすために複数のファイルに分かれているJavaScriptを1つのファイルにまとめます。

JavaScriptを複数ファイルに分けた悪い例:

<script src="http://www.example.com/menu.js"></script>
<script src="http://www.example.com/ajax.js"></script>
<script src="http://www.example.com/nav.js"></script>
<script src="http://www.example.com/tools.js"></script>
<script src="http://www.example.com/footer.js"></script>
<script src="http://www.example.com/others.js"></script>

JavaScriptを1ファイルにまとめた良い例:

<script src="http://www.example.com/combined-all.js"><</script>

上の例では、ファイルを1つに統合することにより6回発生していたHTTPリクエストを1回に減らせます。
アクセス数の多いサイトでは特に効果が期待できます。

2. CSSの参照タグをJavaScriptの参照タグよりも先に記述する

HTMLのheadセクションでは、スタイルシートの参照を先に記述しその後にJavaScriptの参照を記述します。

JavaScriptタグよりも後ろにCSSタグを記述する悪い例

<head>
  <script src="http://www.example.com/nav.js"></script>
  <script src="http://www.example.com/tools.js"></script>
  <script src="http://www.example.com/footer.js"></script>
  <link rel="stylesheet" type="text/css" href="stylesheet1.css" />
  <link rel="stylesheet" type="text/css" href="stylesheet2.css" />
</head>

JavaScriptタグの前にCSSタグを記述する良い例

<head>
  <link rel="stylesheet" type="text/css" href="stylesheet1.css" />
  <link rel="stylesheet" type="text/css" href="stylesheet2.css" />
  <script src="http://www.example.com/nav.js"></script>
  <script src="http://www.example.com/tools.js"></script>
  <script src="http://www.example.com/footer.js"></script>
</head>

JavaScriptは読み込みが始まるとその読み込みが完了して実行されるまでは次のコードの読み込みが始まりません。
待ち時間が発生するわけですね。

一方でスタイルシートの読み込みは複数が同時に行えるし完了していなくてもJavaScriptファイルを含む他のファイル読み込むことができます。

元記事には書いていないことの補足として、特に良くないのは複数のスタイルシート参照の間にJavaScript参照を挟んでしまうことで速度を大きく低下させる可能性があります。

CSS参照タグの間にJavaScript参照タグを挟むとても悪い例

<head>
  <script src="http://www.example.com/nav.js"></script>
  <link rel="stylesheet" type="text/css" href="stylesheet1.css" />
  <script src="http://www.example.com/tools.js"></script>
  <link rel="stylesheet" type="text/css" href="stylesheet2.css" />
  <script src="http://www.example.com/footer.js"></script>
</head>

3. プロトコルを省略する

JavaScriptの外部ファイルを示すURLから http: または https: といったプロトコル(スキーム)を省略します。
省略することでファイルサイズを(ごくわずかだけれど)小さくできます。

プロトコルを省略しない悪い例:

<script src="http://www.example.com/scripts/javascript.js"></script>

プロトコルを省略した良い例:

<script src="//www.example.com/scripts/javascript.js"></script>

プロトコルが省略されている時はそのページの表示に使われている(ブラウザのアドレスバーに表示される)プロトコルが自動的に適用されます。

つまり https: で表示しているなら参照先にも自動的に https: が使われます。

ちなみにJavaScriptだけでなくCSSでも画像でも何でもプロトコルはURLから省略可能です。
ただし省略した場合は、http: なら http: で、https: なら https: でその外部リソースを参照できなければなりません。

4. script要素のtype属性を省略する

HTML5に限りますが、script要素におけるtype属性すなわち type="text/javascript" を省略します。
HTML5では、script要素のtype属性の初期値が "text/javascript" になっているからです。

省略することで(ごくわずかに)ファイルサイズを小さくできます。

type属性を省略していない悪い例:

<script src="//www.example.com/scripts/javascript.js" type="text/javascript"></script>

type属性を省略した良い例:

<script src="//www.example.com/scripts/javascript.js"></script>

なおHTML5では、style要素のtype属性の初期値は "text/css" になっているので type="text/css" も同様に省略可能です。

5. Expiresヘッダーでキャッシュ期間を長くする

ブラウザは1度ダウンロードしたデータをローカルにキャッシュします。
再度同じデータが必要になった時はローカルにキャッシュがあればサーバーにリクエストせずにキャッシュデータを利用します。
すでに自分が持っているデータを使うのでレスポンスが速くなります。

キャッシュは期限が切れると削除されますが、ExpiresというHTTPヘッダーを使うとキャッシュ期間の強制的な指定が可能です。

ウェブサーバーがApacheの場合、.htaccessまたはhttpd.confでExpiresヘッダーを設定するとJavaScriptのキャッシュ期間を制御できます。

たとえば下のように記述できます。

<IfModule mod_headers.c>
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType text/javascript "access plus 4 weeks"
ExpiresByType application/x-javascript "access plus 4 weeks"
ExpiresByType application/javascript "access plus 4 weeks"
</IfModule>
</IfModule>

JavaScriptファイルに最初にアクセスした時から4週間が過ぎるとキャッシュが期限切れして消えます。
言い換えると4週間はローカルにキャッシュが残ります。

期間の指定方法には種類があります。
詳細はApacheのドキュメントを参照してください。

なおサーバーにmod_expiresモジュールがインストールされていないと機能しません。

またJavaScriptだけでなく他のコンテンツのキャッシュ期間の制御にもExpiresヘッダーは使えます。

僕は画像ファイルのキャッシュ期間も設定しています。

ExpiresByType image/gif "access plus 4 weeks"
ExpiresByType image/jpeg "access plus 4 weeks"
ExpiresByType image/png "access plus 4 weeks"

ファイルタイプ(MIMEタイプ)の指定もApacheのドキュメントを読んでください。

JavaScriptのファイルタイプはドキュメントには書かれていなくて調べたところいくつかあるようです。
サーバーの環境や利用しているCMSによって違っていて一般的に使われている3つの種類を僕は記述しています。

具体的な記述は元記事に書かれていません。
僕が自分で調べて以前から利用していた記述を紹介しました(もっと適切な記述を知っていたら教えてください)。

キャッシュ期間をどのくらいに設定するかが問題ですが、これは自分で考えてもらうしかありません。
僕が設定している「4週間」に合理的な意味があるわけではありません。
「これくらいでいいかな」で決めました。(笑)
※RFCに従えば1年以上の期間を指定してはいけないようです。

またhttpd.confではなくて.htaccessに書くのなら「4 weeks」よりも数値のほうがパフォーマンスがよくなるかもしれません。

注意しなければならないことは、まったくあるいはほとんど更新がない静的なファイルにExpiresヘッダーを使うことです。
更新してもキャッシュを使ってしまうのでブラウザに残っている古いデータが使われてしまうからです。

更新した場合はファイルの名前を変えるといいでしょう(初めてリクエストするファイルにしてしまう)。

キャッシュの制御としてはプロキシキャッシュを活用することもできます。

元記事には簡単にしか触れられていないので僕自身で調べた解説になります。

たとえば通信経路途中のISPでプロキシサーバーが使われているときは、そのプロキシサーバーにもファイルがキャッシュされます。

たとえあなたが初めてアクセスするサイトであっても同じプロキシサーバーを利用している他のユーザーがアクセスしたことのあるページであればプロキシサーバーにあるキャッシュデータが返されます。

ウェブサーバーまでの通信が発生しないので応答スピードが結果として速くなります。

プロキシキャッシュをコントロールするにはCache-Controlヘッダーを設定します。

たとえばこんなふうに記述できます。

<IfModule mod_headers.c>
<FilesMatch "\.(jpg|png|gif|swf|ico|css|js)$">
Header set Cache-Control "max-age=2419200, public"
</FilesMatch>
</IfModule>

JavaScript以外にも、画像やCSSなどのその他の静的ファイルも含めています。
キャッシュの保持期間は4週間にセットしてあります。

注意点があります。

CSSとJavaScriptをCache-Controlヘッダーでキャッシュさせるときは、ある製品のプロキシサーバーではバグによりうまく機能しないことがあるようです。

Vary: Accept-Encoding ヘッダーを併用することで回避できます(たいていのサーバーでは実装されているはず。詳細は最後に載せるドキュメントで確認してください。)。

6. コメントを削除する

JavaScriptファイルに書き込まれている不要なコメントを削除します。

フィアルサイズが小さくなりブラウザの読み込みが速くなります。

HTMLファイルやCSSファイルにもコメント削除の効用は当てはまります。

もっとも体感的にどのくらいスピードアップするかどうかは疑問ですけどね。
「やれるならやっておけば」程度でしょうか。

以上がウェブサイトでのJavaScriptの読み込みを最適化してウェブページの表示速度を改善する6つの方法です。

キャッシュのところがひょっとすると難しかったかもしれませんね。

もっとも動きを知らなくても.htaccessに追加すれば普通は機能するので何も考えずに実装することができるでしょう(とは言え自己責任でお願いします)。

JavaScriptファイルの統合と参照タグの配置についてはあなたのサイトではどうなってるかさっそく見直してみてください。

余分な記述を省くファイルサイズの削減による読み込み速度の改善は目に見えるほどの大きな効果はなような気がしますが気休め程度にやってみるのも悪くはないはずです。

今回、利用を許可してくれたJoydeep氏の記事を日本語解説する際は、理解度を確かにしてうまく説明できるように自分でもいろいろ調べました。

調べる過程で発見したのですが、Joydeep氏は以下のドキュメントからも多数の情報を引っ張ってきています。
すべて英語になりますが、より詳しいことに加えてJavaScript以外のスピードアップ方法もたくさん説明されているので読んでおくと絶対に得します。