GAE や Google Closure Library などの話題を扱います。python 初心者です。

2010年1月23日土曜日

Closure Library を Closure Compiler でコンパイル

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク
JavaScriptファイルの圧縮
下記が非常に参考になった。
Closure Library で作る簡易ドローツール(Python Hack-a-thon #3 資料) - WebOS Goodies

まだまだ日本語情報が少ない中、Closure Tools に関する貴重な情報がたくさん載っている。

このページの中の「JavaScriptファイルの圧縮」を参考にして、Closure Library を使った簡単な JavaScriptをコンパイルしてみる。

レシピ
まず HTMLファイル:html/button-min.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

    <script src="http://closure-library.googlecode.com/svn/trunk/closure/goog/base.js"></script>
    <script src="/js/button.js"></script>
    <link rel="stylesheet" href="/css/dialog.css">
    <link rel="stylesheet" href="/css/button.css">
  </head>
  <body>
    <h1>Closure Libraray: button sample</h1>
    <hr/>

    <h2>(1) goog.ui.Button</h2>
    <div id="button1"></div>

    <h2>(2) goog.ui.decorate</h2>
    <div id="button2" class="goog-custom-button">
      <span style="color: blue">BUTTON-<b>2</b></span>
    </div>

    <div id="button3" class="goog-custom-button">
      <span style="font-size: 7pt">BUTTON-<b>3</b></span>

    </div>

  <script>
    setupButtons();
  </script>

  </body>
</html>

goog.ui.CustomButton や decorate を使っている。Closure Library はとりあえず googleのサイトを参照している(コンパイル後に取り除く予定)。

JavaScriptファイル:js/button.js
goog.require('goog.ui.CustomButton');
goog.require('goog.ui.decorate');

function setupButtons() {
        var btn1 = new goog.ui.CustomButton('BUTTON-1');
        btn1.render(goog.dom.$('button1'));
        goog.events.listen(btn1, goog.ui.Component.EventType.ACTION,
            function(e) {
                var target = e.target;
                alert('button1: ' + target);
            }); 

        var btn2 = goog.ui.decorate(goog.dom.$('button2'));
        goog.events.listen(btn2, goog.ui.Component.EventType.ACTION,
            function(e) {
                var target = e.target;
                alert('button2: ' + target);
            }); 
        var btn3 = goog.ui.decorate(goog.dom.$('button3'));
}

ボタンの定義を行っている。button-min.html の最後で setupButtons()が呼び出される。

実行するとこんな画面が出る。

コンパイル
やってみよう。

closure ライブラリは ~/Development/closure-tools/closure に、
closuer compiler は ~/Development/closure-tools/compiler にあるとする。

python ~/Development/closure-tools/closure/bin/calcdeps.py \
            -i button.js \
            -p ~/Development/closure-tools/closure \
            -o compiled \
            -c ~/Development/lib/closure-tools/compiler/compiler.jar \
            -f "--comilation_level=ADVANCED_OPTIMIZATIONS" > button-min.js
calcdeps.py: Scanning files...
calcdeps.py: Finding Closure dependencies...
calcdeps.py: Compiling with the following command: java -jar /Users/hashi/Development/lib/closure-tools/compiler/compiler.jar --js /Users/hashi/Development/closure-tools/closure/go
   :
   :
.js --js /Users/hashi/Development/closure-tools/closure/goog/ui/custombutton.js --js button.js --compilation_level=ADVANCED_OPTIMIZATIONS
$

数分後に button-min.js が生成された(PowerPCは今となっては非力でとても重い..)。
$ ls -l 
total 48
-rw-r--r--  1 hashi  hashi  19163  1 22 21:35 button-min.js
-rw-r--r--  1 hashi  hashi    593  1 22 21:18 button.js

サイズが大きくなっているのは Closure Library を取り込んでいるため。

中身はこんな感じ。


これで元の JavaScriptを差し替えてみよう。

新バージョン
button-min.html を書き換える。
書き換え前:
  6     <script src="http://closure-library.googlecode.com/svn/trunk/closure/goo    g/base.js"></script>
  7     <script src="/js/button.js"></script>
これを下のようにする。
書き換え後:
  6     <script src="/js/button-min.js"></script>

動かしてみよう。

ボタンがうまく表示されていない。問題があるようだ。
Safariのエラーログを見ると setupButtons()が見つけられないとのこと。



ドキュメントを見ると ADVANCED_OPTIMIZATIONS を付けた場合、呼び出しの無い関数は削除されてしまうとのこと。
Advanced Compilation and Externs - Closure Compiler - Google Code

setupButtons()の呼び出しは HTML内だけに記述してあって button.js には定義だけしか書いていない。コンパイラは button.js だけしか見ていないので使われていない関数と判断したようだ。

オプションから ADVANCED_OPTIMIZATIONS を外して再度コンパイルしてみる。
python ~/Development/closure-tools/closure/bin/calcdeps.py \
            -i button.js \
            -p ~/Development/closure-tools/closure \
            -o compiled \
            -c ~/Development/closure-tools/compiler/compiler.jar \
            > button-min.js

$ ls -l
-rw-r--r--  1 hashi  hashi  133677  1 22 22:12 button-min.js
-rw-r--r--  1 hashi  hashi     593  1 22 21:18 button.js
サイズはずいぶん大きくなった。さっきのが 19,163バイトだったので約7倍。

さて実行しなおしてみよう。

出た。

比較
コンパイル前とコンパイル後でどれだけ違うか比べてみた。サンプルは GAEにデプロイしてある。

コンパイル前
http://closuresample.appspot.com/html/button.html

コンパイル後
http://closuresample.appspot.com/html/button-min.html


結果はこの通り。※Safariの Webインスペクタで計測

コンパイル前

コンパイル後


JavaScriptの読み込み時間が8割近く短縮された。全体でも約1/3に短縮。体感速度も全然速い。

- - - -
Closure Compiler は使えそうだ。ただし開発中は未コンパイル状態なのでやっぱり遅いまま。開発効率にかかわるのでどうにか改善したいところだが。

0 件のコメント:

コメントを投稿