以前よりWebページの表示高速化に興味を持っており、その一つとしてリソースのサイズを小さくする努力を行っていました。最近では閲覧環境が多様化し、モバイルデバイスでの閲覧も考慮するようになるにつれ、以前よりもさらにリソースのサイズなどを気にするようになっていました。
そのような中で望んでいたのが、「既存のJavaScriptライブラリから必要な機能のみを抽出して使えるようにならないか」ということでした。嬉しいことに、jQueryの次期バージョン1.8ではついにモジュール化が行われ、grunt(JavaScriptを利用したプロジェクト向けのコマンドラインビルドツール)を利用して不必要なモジュールを除外したカスタムビルド版の生成が行えるようになりました(参考:jQuery 1.8 Beta 1: See What's Coming (and Going!))。
これにヒントを得て、私が気に入って利用させて頂いているJavaScriptライブラリ「MJL」でもカスタムビルドが行えないかテストを行ってみました。MJL登場時のコラムでも述べられている通り、もともと"「必要最小限」の機能だけ実装"されているのですが、私個人の利用状況を詳細に検討すると、よく利用するのが「画像のロールオーバー」と「要素の高さ揃え」、時々利用するのが「タブインターフェイスの実装」と「コア」に当たる機能の一部で、「Adobe Flashオブジェクト埋め込みの機能拡張」などは不必要な事が多いのです。
テスト結果
テスト結果としては、とりあえずカスタムビルド版の生成に成功しました(grunt.jsの記述方法がまだよく分からなかったため、jQueryのカスタムビルドで利用するgrunt.jsをMJL向けに変更して利用しました)。標準のMJL(圧縮版)だと約40KBですが、コア機能と要素の高さ揃え機能に絞ってカスタムビルドを行うと、約12.2KB(圧縮版)と非常にコンパクトになりました。数値化はできておりませんが、ダウンロード時間・スクリプトの評価時間ともにいくらか減少すると考えられます。
また、一度ビルドする環境を整えておけば案件毎に必要な機能を取捨選択してカスタムビルドを行うことが容易になるので、ライブラリ(今回はMJL)に詳しくない方でもコンパクトなライブラリを準備することができます(動作検証などが行われていればよりベター)。
以上のことから、gruntを利用したカスタムビルドは有益ではないかと考えました。
gruntを利用したビルド準備
MJLの分割
まず、MJLを機能毎に分割してmjl/srcディレクトリに格納しました。具体的には、下記のように分割を行いました。
intro.js // MJLに関する情報表記と(function(window) { core.js // 他のファイルに含まれないコアな機能 style.js // stylesheet オブジェクトリスト 操作インタフェイス・スタイルスイッチャ cookie.js // クッキー制御 rollover.js // ロールオーバー flash.js // Flash プラグイン インタフェイス window.js // 新規ウインドウ生成 tab.js // タブインタフェイス生成 equalize.js // 指定要素等高 enable.js // 機能許可インタフェイス outro.js // })(this.window);
grunt.jsの準備
jQueryのカスタムビルドで利用するgrunt.jsをmjl/内に置き、次のように書き換えました。
grunt.initConfig({
pkg: "<json:package.json>",
dst: readOptionalJSON("dist/.destination.json"),
meta: {
banner: "/*! MJL Version <%= pkg.version %> | http://www.mitsue.co.jp/knowledge/mjl.html */"
},
build: {
"dist/mjl.js": [
"src/intro.js",
"src/core.js",
{ flag: "enable", src: "src/enable.js" },
{ flag: "cookie", src: "src/cookie.js" },
{ flag: "style", src: "src/style.js", needs: ["enable", "cookie"] },
{ flag: "rollover", src: "src/rollover.js", needs: ["enable"] },
{ flag: "flash", src: "src/flash.js", needs: ["enable"] },
{ flag: "window", src: "src/window.js", needs: ["enable"] },
{ flag: "tab", src: "src/tab.js", needs: ["enable", "cookie"] },
{ flag: "equalize", src: "src/heightEqualizer.js", needs: ["enable"] },
"src/outro.js"
]
},
min: {
"dist/mjl.min.js": [ "<banner>", "dist/mjl.js" ]
}
});
gruntのタスクの記述も修正しました。
// Default grunt.
grunt.registerTask( "default", "build:*:* min:*" );
gruntのインストール
gruntを利用するにはnodeとnpmが必要です。私はMacOSを利用しており、node.js環境のインストールには@hokacchaさんのnodebrewを使わせていただいてます。nodebrewのREADME.mdに従ってnodebrewをインストールし、その後npm install -g grunt
でgruntをインストールしました。
gruntの実行
mjlディレクトリで下記コマンドを実行すると、デフォルトのMJLがビルドされます。
grunt
ここで、次のように-style,-flashを指定すると、「スタイルスイッチャの実装」と「Adobe Flashオブジェクト埋め込みの機能拡張」を省いたカスタムビルドのMJLが出力されます。
grunt custom:-style,-flash
機能許可インタフェイスを除外(-enable
)した場合は、grunt.jsのneeds指定に基づき画像のロールオーバー・要素の高さ揃えなど6機能全てが除外されます。
grunt custom:-enable
課題など
- カスタムビルドしたMJLを利用する際は、各ブラウザで動作に不具合が生じないか検証する必要があります(機能の依存関係など)。
- GNU 一般公衆利用許諾書に従い、カスタムビルドしたMJLに必要な情報を追記する必要があります。
- jQueryのカスタムビルドで利用されているgrunt.jsを流用したため、ライセンスの確認、またはオリジナルのものを作成する必要があります。