Edited at

browserify の minify する系トランスフォーマーが webpack に比べて圧縮率が悪い

More than 3 years have passed since last update.

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 に追いつけないみたい。