javascriptを一つにまとめる

色々javascriptで作っているうちに、どんどんファイルが増えてくる。今現在でajvascriptファイルだけで30ファイル。ファイルが分かれる分オーバーヘッドが増えるので、一つにできないかと、色々物色。良いのがなければ作る覚悟で。

で、見つけたのがこれ→phpflair.phpってやつ。ライセンスはNew BSDなので導入はしやすい。というか、全部で500行程度のプログラム。gzip圧縮にも対応している。cssとajvascriptをまとめて、圧縮できる。

カスタマイズ方法はというと、ソースを書き換えろと。あっそう。。

if (isset($_REQUEST['js'])) {
	$config['type'] = 'js';

	if($_REQUEST['js'] == 'jquery'){
		$config['sources'] = array(
				"../../common/js/jquery-1.6.2.min.js",
				"../../common/js/jquery.json-2.3.min.js",
				"../../common/js/ui/jquery.ui.core.js",
				"../../common/js/ui/jquery.ui.widget.js",
				"../../common/js/ui/jquery.ui.accordion.js",
				"../../common/js/ui/jquery.ui.mouse.js",
				"../../common/js/ui/jquery.ui.draggable.js",
				"../../common/js/jquery.cookie.js",
				"../../common/js/jquery.mousewheel.js",
								   );
・
・

ということで、こんな感じで、jqueryをまとめて、出力できるようにした。9個のファイルが1つになるので、サーバーと回線にやさしいはず。

で、ここで問題が起こった。今使ってるサーバーはhtmlファイルを外部に出力する際、クライアントが対応していればgzip圧縮して出すような設定になってる。具体的にはhttpd.confに’php_value zlib.output_compression = 1’と設定してある。この設定を外すと動く。なんだよ、htmlをgzip圧縮するか、javascriptをまとめるかの2択か?。ってそんなわけ無いだろ。

結局、phpflair.phpの方はgzip圧縮がかからないように設定する。設定というか、ソースを編集して、compress_methodをnoneにしてやる。

// compression method based on browser support; gzip, deflate, or none
if (!isset($_SERVER['HTTP_ACCEPT_ENCODING'])) {
	$config['compress_method'] = 'none';
} else if (stristr($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip')) {
	$config['compress_method'] = 'gzip';
} else if (stristr($_SERVER['HTTP_ACCEPT_ENCODING'], 'deflate')) {
	$config['compress_method'] = 'deflate';
} else {
	$config['compress_method'] = 'none';
}
// $config['compress_method'] = 'gzip'; // override

$config['compress_method'] = 'none';  ← オーバーライトする。

でも、動かない。ブラウザでみると、Encodingはgzipで、content-typeはtext/javascriptでちゃんと来てるんだけど、javascriptが途中でエラーになる。出てきたjavascriptをデバッグしてみると、途中で切れてるっぽい。。なんかおかしい・・と、header()の部分をコメントにして動かしてみると、content-typeはtext/htmlになっちゃうが一応最後まで受信できる。。うーーん?。
phpのzlib.output_compressionの設定は何で判断しているんだ?。拡張子で判断しているわけでもない、content-typeで判断しているわけでもない。と、header()をひとつずつコメントアウトしながら動かしてみた。

header('Content-Type: '.$config['content_type']);
//header('Content-Length: '.$combined_filesize);   ←こいつ
if ($config['compress_method'] == 'gzip') {
	header('Content-Encoding: gzip');
} else if ($config['compress_method'] == 'deflate') {
	header('Content-Encoding: deflate');
}

なるほど・・。Content-Lengthを指定しちゃうと、phpのzlib.output_compressionで指定したものと食い違うのでおかしくなる。の、かな?。

ってことで、phpのzlib.output_compressionを1にしたままjavascriptをまとめるphpplair.phpをどうじに使えるようになった。当然、htmlもcssもjavascriptもgzipで出力されるようになった。

効果はというと、うーん、体感速度はあがってないけど、リクエスト数が減ってるのでまぁ気休めというか、そんな感じかね。cacheも出きるようになってるけど、やってない。APCのデータキャッシュに入れてしまうと、メモリから送信されるから、より早くなるかも。