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

  • 8
    Like
  • 0
    Comment
More than 1 year has 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 に追いつけないみたい。