# Comparing uglifyjs and google-closure-compiler

**URL:** <https://discourse.elm-lang.org/t/comparing-uglifyjs-and-google-closure-compiler/2883>\
**Category:** Show and Tell\
**Created:** [January 4, 2019, 9:09pm UTC](https://discourse.elm-lang.org/t/comparing-uglifyjs-and-google-closure-compiler/2883 "2019-01-04T21:09:38Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![christian](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/christian/32/1384_2.png) [@christian](https://discourse.elm-lang.org/u/christian)\
**Post date:** [January 4, 2019, 9:09pm UTC](https://discourse.elm-lang.org/t/comparing-uglifyjs-and-google-closure-compiler/2883/1 "2019-01-04T21:09:38Z")

</div>

## Background

I recently shared the Elm compiler performance boosts we got from upgrading our largest application from 0.18 to 0.19 on Twitter:

> <https://twitter.com/charukiewicz/status/1080681364033282048>

In the replies, there was some discussion about output file sizes. I mentioned that I was using the `google-closure-compiler`, but @evancz replied saying he got better results using `uglifyjs`.

> <https://twitter.com/czaplic/status/1081161007215579137>

> <https://twitter.com/charukiewicz/status/1081271924808925185>

Evan suggested moving the discussion to Discourse:

> <https://twitter.com/czaplic/status/1081278841509822466>

## UglifyJS vs Closure Compiler comparison

#### My project stats

- 88 modules get recompiled upon removing the `elm-stuff` directory and running `elm make`
- The project is roughly 24,535 source lines of Elm code
- The output .js file after initial compilation is 54,259 lines

#### Output sizes

Below are the output sizes listed from largest to smallest. You can see that there is some disparity between `uglifyjs` and `google-closure-compiler` initially. The final result after `gzip` is that the two are within 1% of one another in terms of size, with GCC being approximately 500 bytes smaller than the uglifyjs output.

| Method | Gzip | Output Size |
| --- | --- | --- |
| `elm make` | No | `1728593 bytes` |
| `elm make --optimize` | No | `1602466 bytes` |
| `elm make --optimize + uglifyjs` | No | `386604 bytes` |
| `elm make --optimize + google-closure-compiler` | No | `365266 bytes` |
| `elm make --optimize + uglifyjs` | Yes | `109232 bytes` |
| `elm make --optimize + google-closure-compiler` | Yes | `108702 bytes` |

#### `uglifyjs` configuration

This script is adapted from the script in [Evan’s post](https://elm-lang.org/0.19.0/optimize) about optimizing Elm. I have not changed the arguments supplied at all. I am using the latest version of the [`uglify-js`](https://www.npmjs.com/package/uglify-js) package on npm (version 3.4.9).

```auto
#!/bin/sh

set -e

js="app.js"
min="app.uglify.min.js"

uglifyjs $js --compress 'pure_funcs="F2,F3,F4,F5,F6,F7,F8,F9,A2,A3,A4,A5,A6,A7,A8,A9"ure_getters,keep_fargs=false,unsafe_comps,unsafe' | uglifyjs --mangle --output=$min

echo " Initial size: $(cat $js | wc -c) bytes ($js)"
echo "Minified size: $(cat $min | wc -c) bytes ($min)"
echo " Gzipped size: $(cat $min | gzip -c | wc -c) bytes"

```

#### **`google-closure-compiler` configuration**

I’m using the latest version of the [`google-closure-compiler`](https://www.npmjs.com/package/google-closure-compiler) package on npm (version v20181210). There are no special arguments being provided.

```auto
#!/bin/sh

set -e

js="app.js"
min="app.closure.min.js"

google-closure-compiler --js=$js --js_output_file=$min

echo " Initial size: $(cat $js | wc -c) bytes ($js)"
echo "Minified size: $(cat $min | wc -c) bytes ($min)"
echo " Gzipped size: $(cat $min | gzip -c | wc -c) bytes"

```

## Sharing your findings

Please feel free to share the results of your own minification findings, particularly if your results do not match up with the ones here.

---

<div class="post-metadata">

**Author:** ![razze](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/razze/32/1650_2.png) [@razze](https://discourse.elm-lang.org/u/razze)\
**Post date:** [January 4, 2019, 11:59pm UTC](https://discourse.elm-lang.org/t/comparing-uglifyjs-and-google-closure-compiler/2883/2 "2019-01-04T23:59:15Z")

</div>

I was looking into optimizing with webpack the other day. And it seems like terser will replace uglifyjs in the webpack defaults.  
Terser also doesn’t need be called two times, I think.

Here is where I got that from

> <https://github.com/parcel-bundler/parcel/issues/2062#issuecomment-424763767>

I also added this issue to talk about improving docs [https://github.com/elm/elm-lang.org/issues/797](https://github.com/elm/elm-lang.org/issues/797)

---

<div class="post-metadata">

**Author:** ![jzxhuang](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/jzxhuang/32/1908_2.png) [@jzxhuang](https://discourse.elm-lang.org/u/jzxhuang)\
**Post date:** [January 9, 2019, 6:53am UTC](https://discourse.elm-lang.org/t/comparing-uglifyjs-and-google-closure-compiler/2883/3 "2019-01-09T06:53:48Z")

</div>

This is interesting, I never heard of `google-closure-compiler` before but it seems to work really well, plus it also transpiles your code, meaning one less dependency to set up!

Using `elm make --optimize` and your configurations exactly, I tested it with [elm-spa-example](https://github.com/rtfeldman/elm-spa-example/), which of course is the benchmark Evan is using in his post.

### UglifyJS

```auto
 Initial size: 370448 bytes (elm.js)
Minified size: 96879 bytes (elm.uglify.min.js)
 Gzipped size: 30597 bytes

```

### Google Closure Compiler

```auto
 Initial size: 370448 bytes (elm.js)
Minified size: 97254 bytes (elm.closure.min.js)
 Gzipped size: 31100 bytes

```

The results are almost identical. GCC also has an option for [advanced compilation](https://developers.google.com/closure/compiler/docs/api-tutorial3), but it doesn’t seem to work with the outputted Elm code.

Considering GCC is a bit faster and will also transpile code, it seems like the way to go!

---

<div class="post-metadata">

**Author:** ![opvasger](https://avatars.discourse-cdn.com/v4/letter/o/8e8cbc/32.png) [@opvasger](https://discourse.elm-lang.org/u/opvasger)\
**Post date:** [January 9, 2019, 7:56am UTC](https://discourse.elm-lang.org/t/comparing-uglifyjs-and-google-closure-compiler/2883/4 "2019-01-09T07:56:01Z")

</div>

Hello ☀ I’m maintaining [elm-minify](https://github.com/opvasger/elm-minify) which uses [terser](https://github.com/terser-js/terser) under the hood. my results for Richards [spa-example](https://github.com/rtfeldman/elm-spa-example) look like this:

#### commands

```auto
git clone git@github.com:rtfeldman/elm-spa-example.git

cd elm-spa-example

elm make src/Main.elm --optimize --output=elm.js

time elm-minify elm.js

```

#### output

```auto
 Initial size: 370448 bytes
Minified size: 93144 bytes
 Gzipped size: 29838 bytes (measured using Node.js zlib)

    real time: 4939 milliseconds
    user time: 6885 milliseconds
     sys time: 116 milliseconds

```

I don’t know exactly why the results are better in this case, but I guess the terser-folks have done more optimizations?

- @christian, would you mind building your project with `elm-minify` once, sending me the results? I’d like to see how it performs with your much bigger project! ☀

- has anyone measured the runtime using `uglify` and/or `closure`?

> [@razze](#):
>
> Terser also doesn’t need be called two times, I think.

Yup, I call terser once, and haven’t had any issues ☀ I did some comparisons for Richard [here](https://github.com/opvasger/elm-minify/issues/23#issuecomment-450806942).

---

<div class="post-metadata">

**Author:** ![christian](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/christian/32/1384_2.png) [@christian](https://discourse.elm-lang.org/u/christian)\
**Post date:** [January 10, 2019, 6:37am UTC](https://discourse.elm-lang.org/t/comparing-uglifyjs-and-google-closure-compiler/2883/5 "2019-01-10T06:37:20Z")

</div>

I tried `elm-minify` after `elm make --optimize` and here are my results:

| Method | Gzip | Output Size |
| --- | --- | --- |
| elm-minify | No | 360298 byes |
| elm-minify | Yes | 105151 bytes |

So `elm-minify` beats `google-closure-compiler` by about 3%. However, the downside is that it also was the slowest of the three methods by a significant margin (this was executed on an AWS EC2 instance of size t2.small, which is what we use for development servers in my company):

| Method | Time | Slowdown Factor |
| --- | --- | --- |
| `google-closure-compiler` | 6.95 seconds | 1.00 |
| `uglifyjs` | 14.4 seconds | 2.07 |
| `elm-minify` | 24.99 seconds | 3.60 |

---

<div class="post-metadata">

**Author:** ![system](https://canada1.discourse-cdn.com/flex035/uploads/elm_lang/original/1X/50a05e53677a2c3b47776d7abd0f113eb50193a1.png) [@system](https://discourse.elm-lang.org/u/system)\
**Post date:** [January 20, 2019, 6:37am UTC](https://discourse.elm-lang.org/t/comparing-uglifyjs-and-google-closure-compiler/2883/6 "2019-01-20T06:37:23Z")

</div>

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.
