Friday, November 25, 2011

ADVANCED_OPTIMIZATIONS in Google Closure Compiler

Google Closure Compiler supports a compilation mode called "ADVANCED_OPTIMIZATIONS". There are official docs but I wanted to highlight a couple interesting aspects of what activating this mode means in practice. These features set closure compiler apart from other minifiers such as UglifyJS and can potentially help to substantially decrease code size. They do, however, come as trade offs that limit your flexibility with using the JavaScript syntax. It is a common myth that advanced optimizations require using JSDoc types (which are then checked by closure compiler). This is not true.

Property renaming

Closure compiler can rename properties.
Of course, this will break, once you call foo['longName'], so be careful :)

Property collapsing

Closure compiler can collapse property chains (which are often used to represent namespaces in JS)
foo$bar$baz (and will eventually be minified with standard variable renaming.
There are various exit conditions when this optimization cannot be applied. Never assign to a global object twice. Don't alias objects in the property chain as in: a = {b: 0}; c = a; c.b = 5;
This optimization reduces code size and can increase execution speed because fewer lookups have to be performed.

The catch

Don't use the module pattern. Code, that includes the module pattern usually will not minify well with closure compiler. Yeah, sorry about that :) This is not because the closure compiler engineers do not like the module pattern (and similar constructs) but rather because invariants that have to exist for the optimizations (and others) described above, can not be (easily) shown for code with very complex runtime semantics.
We recently had an awesome conversation of G+ about how to fix this. The idea is to transform special cases of idiomatic JavaScript (in this case using AMD) to a form that can be efficiently compiled by closure compiler. Lets do this!