Closure compiler can produce truly impressive output, but it comes at a cost. There are additional rules for how one's code must be written – primarily that you must not use reflection/metaprogramming techniques. If any code, including in dependencies, violates these rules, there's often no warning or error. Instead the output JS will just be wrong. Usually it's immediately and unambiguously wrong, with a runtime exception as the application starts, but every once in a while it's wrong in a very subtle way that requires careful debugging.
For various reasons, I end up debugging a disproportionate number of these cases, and I gotta say that the combination of unsafe optimizations plus long slow compile times can make for some unfun times.
IMO the best option is to try very hard not to have a closure-compiler shaped problem. Keep your client-side code small. If you can't do that, compose it out of small, largely independent, lazily loadable modules. And if you can't do _that_, come to terms with it as early as possible and start using Closure Compiler from the beginning.
Because as much trouble as Closure Compiler can be, there's a scale of application where nothing else comes close. It has top tier dead code elimination (not just tree shaking, but proper DCE), can split an application into lazily loadable chunks, will move code between modules, and will perform pervasive type-aware optimizations that AFAIK no other minifier comes close to.
For various reasons, I end up debugging a disproportionate number of these cases, and I gotta say that the combination of unsafe optimizations plus long slow compile times can make for some unfun times.
IMO the best option is to try very hard not to have a closure-compiler shaped problem. Keep your client-side code small. If you can't do that, compose it out of small, largely independent, lazily loadable modules. And if you can't do _that_, come to terms with it as early as possible and start using Closure Compiler from the beginning.
Because as much trouble as Closure Compiler can be, there's a scale of application where nothing else comes close. It has top tier dead code elimination (not just tree shaking, but proper DCE), can split an application into lazily loadable chunks, will move code between modules, and will perform pervasive type-aware optimizations that AFAIK no other minifier comes close to.