[TIMOB-8663] R&D: Evaluate various obfuscation / minification engines for common use across platforms
GitHub Issue | n/a |
---|---|
Type | Sub-task |
Priority | High |
Status | Closed |
Resolution | Fixed |
Resolution Date | 2012-04-17T10:27:06.000+0000 |
Affected Version/s | n/a |
Fix Version/s | Release 2.1.0, Sprint 2012-08 |
Components | Tooling |
Labels | core |
Reporter | Marshall Culpepper |
Assignee | Max Stepanov |
Created | 2012-04-10T15:45:13.000+0000 |
Updated | 2012-06-15T16:29:04.000+0000 |
Description
We need to investigate the various JS obfuscation and minification options in the wild and decide on a common approach across platforms. Some obvious contenders:
* Google Closure Compiler
* YUI compressor
When evaluating the various options, we should keep in mind the ability to feed in more data (i.e. an AST or other API heuristics) to further optimize the minification process
FWIW, the ultimate goal is mobile web's AST parser will eventually replace closure compiler. Like closure compiler, it will obfuscate through minification. There was no plan to further obfuscate the code as that would probably increase file size. Even if we did some sort of encryption or heavy obfuscation, anybody with Web Inspector or Firebug could pretty much defeat any obfuscation. Mobile web is capable of "lazy loading" code, so you could gain a level of obfuscation by pulling down sensitive data after the page loads, but we're not quite there yet with the tooling require to support this.
Our options so far: - [Google Closure Compiler](https://developers.google.com/closure/compiler/) - [YUI Compressor](http://developer.yahoo.com/yui/compressor/) - [UglifyJS](https://github.com/mishoo/UglifyJS) - [/packer/](http://dean.edwards.name/packer/) - mine's favorite, but want to be objective :) - [ShrinkSafe (DOJO compressor)](http://dojotoolkit.org/reference-guide/1.7/util/shrinksafe/index.html) - [All-in-one tool (wro4j)](http://code.google.com/p/wro4j/) will go in detail over each one
Original Example Code:
[ShrinkSafe](http://dojotoolkit.org/reference-guide/1.7/util/shrinksafe/index.html)
Part of DOJO build toolchain. Java-based, utilizes Rhino to parse code. MPL 1.1 license. Safe about public variables and APIs. Almost no configuration options.In order to minimize top level scope variables the whole source code needs to be wrapped into *Immediate function* _(function(){})()_ and then it needs to be stripped of.
[/packer/](http://dean.edwards.name/packer/)
JavaScript-based. [Source code](http://code.google.com/p/base2/source/browse/trunk/src/apps/packer) available. MIT License. Analyses only source code. No AST. Runs 4 phases: minifier, shrinker, privates encoder, base62 encoder. The first 3 phases are pretty ordinary comparing to others. *The most interesting phase is base62 encoder (0-9A-Za-z) which I think we should adapt regardless of chosen engine*.[UglifyJS](https://github.com/mishoo/UglifyJS) (Editor's Choice)
JavaScript-based. Developed on Node.JS. BSD license. Parses AST tree then does various manipulations on it. Highly customizable. Supports variable name reserving. Can return AST as output - might be useful for API heuristics. Performs a lot of optimizations that could potentially lead to a faster code: simple constant expressions, property access as associated array, IF statements optimizations, joins var declarations etc.Has the same issue with shortening _global_ variables as ShrinkSafe. Use of *Immediate function* is encouraged.
[YUI Compressor](http://developer.yahoo.com/yui/compressor/)
Java-based, utilizes Rhino to parse code. MPL 1.1/BSD license. Optional private variables shortening. Pretty much the same as ShrinkSafe.With *Immediate function* trick:
[Google Closure Compiler](https://developers.google.com/closure/compiler/)
Java-based, utilizes Rhino to parse code and build AST. Apache License 2.0 Only SIMPLE_OPTIMIZATIONS could be applied to source code. ADVANCED_OPTIMIZATIONS involves aggressive renaming which will break app if performed w/o declaring externs (literally _all Titanium APIs_). Also ADVANCED_OPTIMIZATIONS removes _dead code_ like functions defined but never explicitly called. See [dangers](https://developers.google.com/closure/compiler/docs/api-tutorial3#dangers) section for the full list of limitations. Could print AST for analysis.Thanks Max.. lots of good info here :) It sounds like ADVANCED_OPTIMIZATIONS in Closure might be a good bet if we can have an up-front declared list of Titanium APIs. Can you try manually creating the list for Closure, and use ADVANCED_OPTIMIZATIONS to see what the output is like?
Also, since many of these use Rhino for parsing the Javascript, would that stop us from using newer ECMA 5 (or eventually Harmony) features in our platform?
Marshall, I would say that using UglifyJS would be the best option. It should be easy to integrate with Node.JS build system if we switch to it. Plus it has configuration options for individual optimizations, rather than simple/advanced in Closure. Plus, since it's all in JavaScript, it will be easier for us to customize/change code. And given your concern about ECMA 5, UglifyJS seems only the option right now.
Marshall, I don't see reasons to test Closure with ADVANCED_OPTIMIZATIONS since in addition to exports list requirement and does other undesirable stuff like dead code elimination and inconsistent property names mess.
Conclusion: *UglifyJS running on top of Node.JS* Also it works with Rhino, but very slow.