wro4jでリソースをminifyし、Jettyでレスポンスをgzip化して通信する。

スマホ向けのブラウザサービスは、モバイル回線で画像などのリソースを大量にやりとりするので、通信のもたつきを感じることが多いです。
ある時、さすがに読み込みが遅いと感じて、JavaScriptとCSSのリソースの容量を確認したら、11ファイルで742KBになっていました。
そこで、JavaScriptとCSSを圧縮することにしました。

wro4jで全てのファイルをminifyする。

まずは、よくminifyと呼ばれることをしました。
minifyとは、JavaScriptやCSSの動作に影響を与えない範囲で、不要なコメント文や空白文字を除去したり、変数名の文字数を減らしたりする処理です。
Javaには、wro4jと呼ばれるリソース圧縮ツールがあるので、これを使いました。
スクリーンショット 2014-04-01 22.31.17
wro4j – Web Resource Optimizer for Java – wro4j – Google Project Hosting
wro4jは、Mavenプラグインとして導入し、ビルド時にリソースの圧縮をかけられるようにしました。


	ro.isdc.wro4j
	wro4j-maven-plugin
	1.7.0
	
		true
		${project.basedir}/src/main/webapp/css/
		${project.basedir}/src/main/webapp/js/
		${project.basedir}/src/main/webapp/
		${project.basedir}/src/main/webapp/WEB-INF/wro.xml
		ro.isdc.wro.extensions.manager.standalone.GoogleStandaloneManagerFactory
	
	
		
			compile
			
				run
			
		
	

JavaScriptとCSSは、wro4jによって複数ファイルの結合とminifyをすることが可能です。どのファイルを圧縮するかの設定は、wro.xmlという設定ファイルに、たとえば次のように書きます。



	
		/js/templates.js
		/js/app.js
	

これだけでJavaScriptなどは、20〜30%くらいは容量を削減することができます。

さらにJettyの設定でレスポンスをgzip化する。

CSSは、minifyの効果があまり大きくありません。なぜなら、類似のスタイルをまとめる構文がないので、必然的に反復記述を減らせないためです。
そこで更に、HTTPの通信の際に、レスポンスボディを丸ごとgzipで圧縮します。
サーブレットコンテナにJettyを使っている場合の例です。
スクリーンショット 2014-04-01 22.32.42
Jetty – Servlet Engine and Http Server
jsファイル、cssファイルのマッピングを org.eclipse.jetty.servlet.DefaultServlet にし、gzipパラメータをtrueにすることでgzip転送を利用できるようになります。

	
		gzipServlet
		org.eclipse.jetty.servlet.DefaultServlet
		
			gzip
			true
		
	
	
		gzipServlet
		/js/*
		/css/*
	

意外と単純です。

事前にgzipファイルを用意しておく必要がある

このJettyのサーブレットによる、gzip転送は、HTTPのリクエストをされるごとにgzip圧縮をするわけではありません。
そのため事前に、非圧縮のファイルとgzip圧縮されたファイルを用意しておく必要があります。

$ ls ./js/
app.js		main.js		main.js.gz	templates.js

こんな風に、main.jsと並列にmain.js.gzを配置しておくことで、gzipされたファイルをレスポンスしてくれます。
ちなみに、両方置いておく必要がある理由は単純です。gzip圧縮による通信に対応していないブラウザが存在するためです。
HTTP通信の際には、gzip圧縮による通信ができるかをリクエストヘッダに添えるので、これを見て、main.js.gzを返すのか、main.jsを返すのかを判断します。

GET / HTTP/1.1
Host: example.com
...
Accept-Encoding: gzip, deflate
...

gzip圧縮されたファイルが用意されていない場合は、ヘッダに関わらず非圧縮のファイルが返されます。

結果、79%も削減できた。

minifyとgzip圧縮によって、容量を742KBから159KBに79%も削減することができました!
モバイルの低速回線だとかなりの体感の差になると思います。

コメント

  1. […] 今までは「wro4jでリソースをminifyし、Jettyでレスポンスをgzip化して通信する。」に書いたように、Mavenにフロントエンドの処理もさせていました。しかし、MavenはJavaのためのツールで、フ […]

タイトルとURLをコピーしました