Comparing Uglify and Closure in Babel/Rollup Javascript Build Environment

Comparing Uglify and Closure in Babel/Rollup Javascript Build Environment

I’ve been experimenting with creating a build environment for a React project that uses Rollup and Babel. One of the choices you can make is how to minify the generated js. I compare using two methods of compacting: Uglify and Closure.

I have a project that uses React, which normally requires compilation with Babel. (For JSX). I’ve been working on a build environment using an advanced JS packaging tool – Rollup. One of the nice things about rollup is that once you have the environment set up its easy to add methods to optimize the generated javascript.

Two good methods are to run the code through either Uglify or Closure. Here is my rollup.config.js, with both enabled:

import babel from 'rollup-plugin-babel';
import commonjs from 'rollup-plugin-commonjs'
import nodeResolve from 'rollup-plugin-node-resolve'
import uglify from 'rollup-plugin-uglify'
import replace from 'rollup-plugin-replace'
import closure from 'rollup-plugin-closure-compiler-js';

export default {
   entry:  'status-react.jsx',
   dest:   '../files/status-react.js',
   format: 'iife',
   plugins: 
   [ 
      babel({ 
         exclude: 'node_modules/**' 
      }),
      closure(),
      nodeResolve({
        jsnext: true
      }),
      commonjs({ 
         include: 'node_modules/**'
      }),
      replace({
         'process.env.NODE_ENV': JSON.stringify( 'production' )
      }),
      uglify({
         compress: {
            screw_ie8: true,
            warnings: false
         },
         output: {
            comments: false  
         },
         sourceMap: false
      })
   ]
};

Uglify is a more standard minifier. It not only does standard minification, but some limited code rewriting like reducing the size of variable names.

Closure is a complete JS compiler. It does a complete analysis, removes dead code, and can do some pretty deep rewriting of your code.

Normally Closure would be much better at compressing JS because it can do much more dead code removal. Rollup does its own dead code removal already – so there is a lot less benefit to using Closure over Uglify in a rollup environment.

With rollup it pretty easy to try both so I did a comparison, using one of my projects.

In this table I compare the rollup compiled JS file, with no minification against using one or the other or both of the minification methods. I give the sizes for the file itself, and after gzip compression (since when transferred the file will likely be gzip compressed):

minification type size gzip size
none 1064k 231k
closure only 352k 95k
uglify only 360k 98k
both 351k 93k

Essentially using at least one minification method has big advantages, but either one or both is about the same. There is a small advantage to using closure – but it barely matters. Closure adds a significant amount of compilation time.

I didn’t test performance of the generated code, so its possible that one of these methods has significantly better performance. At least for now, I’m going to be using just uglify, since it way simpler and faster to compile and generates code that is similar in size.