webpack を使っていた人間が browserify を使ってみたところ、圧縮率が期待通りじゃなかったので少し調べてみた話。
圧縮対象
main.js
var _ = require('lodash');
function printPairs(object) {
console.log(_.toPairs(object));
}
printPairs({
a: 1,
b: 2
});
モジュールの圧縮率を示すために lodash を呼んでます。
圧縮する
$ npm install browserify uglifyify minifyify webpack lodash
# webpack
$ ./node_modules/.bin/webpack --optimize-minimize main.js main-webpack.js
# browserify + minifyify
$ ./node_modules/.bin/browserify -p [ minifyify --no-map ] -o main-minifyify.js main.js
# browserify + uglifyify
$ ./node_modules/.bin/browserify -g uglifyify -o main-uglifyify.js main.js
比較
$ ls -sh1 main-*
64K main-minifyify.js
64K main-uglifyify.js
60K main-webpack.js
今回のコードは 10% 満たない違いしか無いけれど、babel 関係のものを噛ませると 10% 〜 20% くらい差が出る。
原因?
トップレベルスコープの変数名などの圧縮をしていないせいかな?
$ grep printPairs main-*
main-minifyify.js:function printPairs(r){console.log(_.toPairs(r))}var _=require("lodash");printPairs({a:1,b:2});
main-uglifyify.js:function printPairs(r){console.log(_.toPairs(r))}var _=require("lodash");printPairs({a:1,b:2});
# 更に圧縮してみる
$ ./node_modules/.bin/uglifyjs -mt < main-uglifyify.js > main-uglifyify-uglify.js
$ ./node_modules/.bin/uglifyjs -mt < main-minifyify.js > main-minifyify-uglify.js
$ ls -sh1 main-*
60K main-minifyify-uglify.js
64K main-minifyify.js
60K main-uglifyify-uglify.js
64K main-uglifyify.js
60K main-webpack.js
そもそも変数名圧縮云々以前に uglifyify はモジュール1つ1つを圧縮するためのもの、という感じなので、更に圧縮する余地があるのは仕様っぽい。
When using uglifyify you should generally also use Uglify, to achieve the smallest output.
hughsk/uglifyify - JavaScript
実際調べる過程で、github のコード検索をしたら同様のことをしているのを何度かみました。
どうせ zip 圧縮されて配信すればそんなに違いでないけれど、気になるし、多段ソースマップの設定も大変だし、まだ webpack を使いそう。
追記: babel-polyfill も読み込むと
こうなる:
$ ls -sh1 main-*
136K main-minifyify-uglify.js
156K main-minifyify.js
136K main-uglifyify-uglify.js
156K main-uglifyify.js
116K main-webpack.js
更に uglify しても webpack に追いつけないみたい。