JavaScriptの読み込み高速化方法についてまとめてみた

今日はJavaScriptの読み込み高速化手法についていろいろと調べていたのでまとめておきたいと思います。
たぶん暫くの間は覆ることは無いと思いますので・・・。

はじめに

Webページを表示する際に、重要な指針となるひとつの要素に「表示速度」があります。
この表示速度を改善させるためにはいろいろな取り組み方があります。
一般的な取り組み方としては大まかに分けると3つ。

 A.Webサーバーのレスポンス高速化
 B.HTMLから読み込まれる各ファイルサイズを減らす
 C.HTMLから読み込まれるファイル数を減らす

一般的に高速化というとAっぽいのですが・・・・
今回のテーマはJavaScriptなので、ここからは「JavaScript」にスコープを当てて話したいと思います。

JavaScriptの読み込み高速化とは?

JavaScriptにおいて特に問題となるのはBとCになります。
(勿論全部重要なんですが)

Bのファイルサイズの適切化に関してはそんなに難しい話ではなく、所謂「圧縮(難読)化」をすることで
ファイルサイズを小さくしようという話です。Closure Compiler Serviceあたりが有名所ですね。

実際に何を持って圧縮化と言ってるかというと、「変数名を最短文字」にしたり「不要スペースの削除」などがメインです。
あとは圧縮化するライブラリによりますが、不要なループ処理は取り除くとか高機能なのも。
基本テキストファイルなので、勿論文字数が減ればファイル容量も減るわけです。

var sContentsCategoryName = "my works.";
var bDevelopmentMode = false;

var a="my works.",b=false;

 ・変数名を最短文字列(aとかb)へ
 ・イコールの間の半角スペースを取り除く
 ・var定義は同時に定義できるのでカンマ区切り方式へ変更

この作業はほぼ全般のサイトでやるべき事だとは思うのですが、次のCに関しては「必ずしも」では無いかと思います。
既にファイル数が少ないサイト(5個以内位)では効果の望みは薄いかなと。

読み込みファイル数と速度の関係

そもそもJavaScriptで読み込みファイル数が多くなると遅くなるのはscriptタグをブラウザがどう解釈しているか?
がポイントになります。
HTML解析において、scriptタグは発見した直後にページのレンダリング処理を止めてJavaScriptを実行します。
その実行結果が返却された後に再び途中からレンダリング処理を開始すような動きになります。

JavaScriptの読み込みについて

上記の図では、以下の3ファイルが存在します。

 ・headタグ内に書いたhoge.js
 ・bodyの表示要素前に書いたfuga.js
 ・body閉じタグの直前に書いたhogefuga.js

どのJavaScriptもポイントとしてその行に入った直後に「読み込み+実行」を行うという事です。
HTMLをブラウザが解析するときは上から読み込んでいきます。なので、まずはhoge.jsが読み込まれます。

次にbodyタグを処理していくのですが、表示要素よりも手前にfuga.jsがあります。
この場合、scriptタグの下にあるh1はまだ表示されることなく、fuga.jsの読み込み+実行が行われます。
実行が完了した後h1タグは表示されます。

ほぼすべての表示要素が出力を終え、表示上は問題なく出ている直前にhogefuga.jsの読み込み+実行が行われます。

ということで、scriptタグは置けば置くほど読み込み+その場で実行が増えます。
要はJavaScriptを読みこめば読み込むほど遅くなる。

読み込むファイル数を減らす方法

1.全部くっつけて1ファイルにする

「無茶言うな」っていう話ですが、まぁ理論上はこれです。
でも今jQueryとかライブラリとか使いまくってるし、機能単位で分けるのは当然なので無理ですよねー・・・。

 ・良い所:リクエスト数が最小、一番高速
 ・悪い所:実用的ではない。

2.ノンブロッキング(非同期)でJavaScriptファイルを読み込む

これはお手軽です。JavaScriptファイルを非同期で読み込み、全部読み込み終わった後に
上から順番に実行すればOK。非同期でJavaScriptを読み込んで後でまとめて実行するので、
読み込んでいる間のHTML描画を妨げません。また、ブラウザの同時リクエスト数が多いブラウザ
であれば、同時に複数のJavaScriptファイルを読み込めるので特に有効です。
私が知ってるのだとhead.jsとかLABjsとかです。

但し、これも大量のJavaScriptファイルを処理させようとするといくら非同期で読み込むとはいえ
多くのリクエストを処理することとなりますので、量によっては動作遅延問題になります。

 ・良い所:HTML描画を邪魔せずにJavaScript読み込みができる。実行順序の担保も出来る。
 ・悪い所:大量のファイルを読みこませるとブラウザのリクエスト処理数を上回り遅くなる。

3.ファイル結合システムを使って1ファイルにする

1で書いた「全部くっつけて」というものをPHPなどのプログラムを通して1ファイルにしてしまう
というものです。これはオープンソースあるのかな・・・?

とりあえず、Header自体をJavaScript出力設定にしてしまえばOK。
PHPならこんな感じ。

 header("Content-Type: text/javascript; charset=UTF-8");

で、処理的にはリクエストで受け付けたファイルをサーバー側で読み込み全部まとめたものを返却。
PHP処理分サーバー側に負荷がかかりますが、そこはPHPなのでいろいろと仕組みを用意しましょう。

 ・1度くっつけたパターンはキャッシュファイルを生成して、次のアクセス時はそれを利用する
 ・結合対象のファイル更新時刻が変わっていたらキャッシュファイルを作りなおす

こんなの作っておけばいいですね。

まとめ

ということで、JavaScriptの読み込み高速化をする場合は以下の順番で実現ができるかどうかを
考えましょう。

 1.JavaScriptファイル結合システムの準備をする
 2.ノンブロッキングJavaScriptライブラリを用いて非同期読み込みを行う

あ、上記に関わらずbody閉じタグ直前でscriptタグを書くようにするのは言うまでもありません。