mishoo/UglifyJS2 — pull request #425 by mattbasta (2014-02-07 19:13:42+00:00)
Title: Add option to alphabetize object literals during compression

This patch adds the option to have object literals alphabetized. This provides no direct size benefit, but can have very large benefits after gzipping. Consider the following example:

```js
foo({
a: function() {/* ... */ return x;},
b: function() {/* ... */}
});
bar({
b: function() {/* ... */},
a: function() {/* ... */ return x;}
});
```
Gzip can't do much on the above example. If the object literals were alphabetized, though, the end of `a` and the key and function for `b` would be compressed away.

This has notable benefits in codebases that use a very Java-esque means of providing inheritance (i.e.: using some sort of `extend` function and declaring each method as a key in an object literal). A module may expose an "abstract class" which is meant to be implemented multiple times. The keys in the implementing "class"'s object literals may be in different orders, though, and if some of those members are the same or similar, that's a missed opportunity for compression:

```
var AbstractClass = Base.extend({
size: function() {throw new Error('implement me');},
capacity: function() {throw new Error('implement me');},
add: function(item) {
this.data.push(item);
}
});
var ArrayClass = AbstractClass.extend({
size: function() {return this.data.length;},
capacity: function() {return this.max_len;}
});
var MockedArrayClass = AbstractClass.extend({
add: function() {}, // no-op
capacity: function() {return this.max_len;},
size: function() {return this.fake_len;}
});
```

In the above example, reordering `capacity` and `size` will allow gzip to do a better job of compressing the `MockedArrayClass`.

The only potential downside here is that normally-adjacent keys in an object literal (which are grouped by similarity) may no longer be adjacent if there's another key that falls between them alphabetically, which can reduce the opportunity for compression. This is a somewhat contrived case, but it's the reason why I included the change under its own option and made it disabled by default.