question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Fixing the google-closure-compiler advanced mode

See original GitHub issue

The ADVANCED mode of the Closure Compiler is pretty strict, and any error make it fails. You’ll need to provide sufficient information about all variables used in the library to minify in order to use it.

As you can’t of course do that here, one (very) ugly way to avoid failure of minification would be to set the jscomp_off flag to '*' in google-closure-compiler.advanced.js.

I tried running it and here are the results, however I didn’t test each library to see if it works. What do you think about it?

📋 Results

d3 v6.7.0

  • Unminified size: 560.0 kB
  • Unminified Gzip size: 131.4 kB
Minifier Minified size Minzipped size Time
google-closure-compiler.advanced 🏆-54% 260.6 kB 🏆-30% 92.8 kB 🏆 13 796ms

jquery v3.6.0

  • Unminified size: 288.6 kB
  • Unminified Gzip size: 85.1 kB
Minifier Minified size Minzipped size Time
google-closure-compiler.advanced 🏆-70% 87.4 kB 🏆-62% 32.5 kB 🏆 6 725ms

lodash v4.17.21

  • Unminified size: 544.1 kB
  • Unminified Gzip size: 97.3 kB
Minifier Minified size Minzipped size Time
google-closure-compiler.advanced 🏆-89% 60.2 kB 🏆-79% 20.9 kB 🏆 7 491ms

moment v2.29.1

  • Unminified size: 173.9 kB
  • Unminified Gzip size: 36.5 kB
Minifier Minified size Minzipped size Time
google-closure-compiler.advanced 🏆-72% 49.6 kB 🏆-52% 17.6 kB 🏆 5 150ms

react v17.0.2

  • Unminified size: 72.1 kB
  • Unminified Gzip size: 19.5 kB
Minifier Minified size Minzipped size Time
google-closure-compiler.advanced 🏆-65% 25.4 kB 🏆-52% 9.4 kB 🏆 4 115ms

terser v5.7.0

  • Unminified size: 869.4 kB
  • Unminified Gzip size: 174.5 kB
Minifier Minified size Minzipped size Time
google-closure-compiler.advanced 🏆-58% 368.9 kB 🏆-33% 118.5 kB 🏆 9 117ms

three v0.124.0

  • Unminified size: 1.2 MB
  • Unminified Gzip size: 249.0 kB
Minifier Minified size Minzipped size Time
google-closure-compiler.advanced 🏆-58% 527.6 kB 🏆-41% 148.5 kB 🏆 12 824ms

vue v2.6.12

  • Unminified size: 223.2 kB
  • Unminified Gzip size: 62.3 kB
Minifier Minified size Minzipped size Time
google-closure-compiler.advanced 🏆-69% 71.3 kB 🏆-55% 28.2 kB 🏆 5 966ms

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Reactions:1
  • Comments:13 (6 by maintainers)

github_iconTop GitHub Comments

1reaction
kzccommented, Jun 6, 2021

lodash.closure-advanced.js in the test above failed because of property mangling in the commonjs bundle which broke the library’s API.

Given the following commonjs library input:

exports.some_calculation = function(x, y){ return x * y }

google closure compiler with simple settings produces:

exports.some_calculation=function(a,b){return a*b};

and google closure compiler with advanced settings produces:

exports.g=function(a,b){return a*b};

The last result is indeed smaller, but it will not work correctly in a NodeJS application because it changed the library’s API.

If you want to compare apples with apples and produce comparable sizes to the google-closure-compiler.advanced settings, just enable --mangle-props on uglify-js and terser to further reduce sizes:

$ uglify-js d3.js -mc | wc -c
  265371

$ uglify-js d3.js -mc --mangle-props | wc -c
  247041

In this case it produced a result that was 7.4% smaller. But the results are meaningless without tests to verify the minified libraries.

1reaction
kzccommented, May 2, 2021

however I didn’t test each library to see if it works

@privatenumber minification-benchmarks ought to run the generated minified libraries against test programs to determine whether they are valid.

I don’t have the java runtime on my machine needed to run Google Closure Compiler, but I pasted the contents of node_modules/lodash/lodash.js into https://closure-compiler.appspot.com/home, and clicked the Advanced and Compile buttons, and then pasted the result into lodash.closure-advanced.js. This file was unable to run the sample verification code below unlike the other minified libraries could. lodash.closure-simple.js (used below) was also produced in a similar way using the Simple button in the Google Closure Compiler web app - and it did work correctly.

Here’s a crude lodash library test harness:

#!/bin/sh
for i in \
    node_modules/lodash/lodash.js \
    lodash.uglify-js.js \
    lodash.terser.js \
    lodash.esbuild.js \
    lodash.closure-simple.js \
    lodash.closure-advanced.js \
    ; \
do
    echo
    # show library name and size
    wc -c $i
    # test this library in node - it should output "25" if successful
    CODE="var _=require('./$i');console.log(_.flow([_.add, x=>x*x])(2,3));"
    echo $CODE
    node -e "$CODE"
done

when it is run it produces:

  544098 node_modules/lodash/lodash.js
var _=require('./node_modules/lodash/lodash.js');console.log(_.flow([_.add, x=>x*x])(2,3));
25

   69674 lodash.uglify-js.js
var _=require('./lodash.uglify-js.js');console.log(_.flow([_.add, x=>x*x])(2,3));
25

   71408 lodash.terser.js
var _=require('./lodash.terser.js');console.log(_.flow([_.add, x=>x*x])(2,3));
25

   72841 lodash.esbuild.js
var _=require('./lodash.esbuild.js');console.log(_.flow([_.add, x=>x*x])(2,3));
25

   73570 lodash.closure-simple.js
var _=require('./lodash.closure-simple.js');console.log(_.flow([_.add, x=>x*x])(2,3));
25

   58456 lodash.closure-advanced.js
var _=require('./lodash.closure-advanced.js');console.log(_.flow([_.add, x=>x*x])(2,3));
TypeError: Cannot set property 'placeholder' of undefined

Each library benchmarked should have similar verification code to disqualify invalid minified libraries.

I didn’t test swc and babel-minify.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Advanced Compilation | Closure Compiler
To ensure proper compilation, compile all the code for a page together in a single compilation run. The Closure Compiler can accept multiple ......
Read more >
ADVANCED mode java.lang.IllegalStateException #3944
Version: v20220502 I use closure-compiler in ADVANCED mode and get java.lang. ... IllegalStateException at com.google.common.base.
Read more >
Google closure compiler ADVANCED mode breaks code
I'm used this command line for compiling script. java -jar closure-compiler.jar --compilation_level ADVANCED_OPTIMIZATIONS --js script.js. When ...
Read more >
Using the Closure Compiler - ADVANCED_OPTIMIZATIONS
It will run a deep analysis of your code and apply a series of advanced optimizations like dead code removal, function flattening and...
Read more >
ClojureScript - Google Closure
Google's Closure compiler provides an advanced setting allowing a much more aggressive minification strategy than that outlined above.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found