Play2 でのアセット最適化方法を考える

Play2 で CSS、JavaScript、画像などアセットに対して以下の最適化を実現する方法を考えます。

  • URL にバージョンを付与する
  • 長いキャッシュ期間を設定する
  • CSS や JavaScript ファイルを結合する
  • CSS や JavaScript を minify する

URL にバージョンを付与する

Play2 にこの機能を追加するための チケット が最近作られました。リンク先にあるように controllers.Assets のかわりに controllers.VersionedAssets を使うだけで、リバースルーティングで参照した URL に v=1345454540000 のようなバージョンが付与されます。

超簡単で良いのですが、CSS 内の URL をどうするかという問題が残っています。

background-image: url(/images/icon.gif)

といった記述も

background-image: url(/images/icon.gif?v=1234567)

となってほしいわけです。

コンパイル時に置換するタスクが必要になりそうですね。

長いキャッシュ期間を設定する

URL にバージョンを付与したら、次はキャッシュ期間を長く設定し一度ダウンロードしたバージョンの再ダウンロードを避けます。 application.conf で Play2 ビルトインの controllers.Assets を設定します。

### すべてのファイルについて 1 年に設定する
assets.defaultCache="max-age=31536000"

### 個別のファイルごとに設定する
"assets.cache./public/stylesheets/main.css"="max-age=60"

これで指定した max-age で Cache-Control ヘッダがレスポンスに付与されるようになります。 なお controllers.Assets は ETag をレスポンスに出力しますが Cache-Control があれば必要ないので前段の Web サーバーで削除しておくのが良いでしょう。

CSS や JavaScript ファイルを結合する

結合してリクエスト数を減らします。 残念ながらこのための機能は提供されていませんが、CSS に関しては LESS の @import で実現することができます。

/app/assets/stylesheets に

  • _common.less
  • _form.less
  • _side-bar.less
  • type1.less

があるとして、type1.less を以下の内容にしておくと、_common.less, _form.less が含まれた形で type1.css が生成されます。

type1.less:

@import "_common";
@import "_form.less";

部品の less ファイルには先頭 _ (アンダースコア) をつけておくと個別の css ファイルが生成されません。

CSS や JavaScript を minify する

LESS コンパイラが minify した css ファイルを作ってくれます。 上の例だと type1.min.css が作られます。

まとめ

現時点では十分な機能が提供されているわけではないですが、CSS 内の URL バージョン化と JavaScript 結合をあきらめればまあまあ使えそう。 ビルド、パッケージング、実行まで統合している Play なら、ほとんど設定なしでもうまーくやってくれる仕組みを作ることができるかもしれませんね。チケットもできたことだし、今後に期待したいところです。