Общо показвания

април 08, 2012

One more thing on javascript minification

There seem to be some very troubling misunderstanding that arises when one go on the hunt for compression technology for javascript: most comparison is made on two false assumptions.
  1. Closure compiler should be used in simple mode
  2. Code size measurement should be done when using either libraries not written in the required for advanced optimization style or using own application code.
Here is why those two are fallacies!

I will start with number two - unused code from libraries and utilities.
In advanced mode the compiler makes something no other compression tool out there is able to do (including uglifyjs, as confirmed by Mihai Bazon this is even not in their scope): the compiler is able to determine the types as if it was run-time and thus strip code paths that were never utilized.

Most code is written to be application agnostic and thus contains lots and lots of methods and functions and variables that are never used in an application. All those contribute to slow execution because they a) need to be parsed and then b) evaluated

Here is an example code
Car = function(color) {
  this.color_ = color;
  this.mileage_ = 0;
};

Car.prototype.drive = function( direction ) {
  this.mileage_ ++;
};

var n = new Car('black');
console.log(n.color_);
UglifyJS currently is completely unable to identify the fact that, should this be considered the whole project code, the drive method and the mileage_ property are never used. Even more, when posted this on the discussion group I гot pointed out that considering the following additional code:
function driveCar(c) { c.drive() }
uglify is not able to determine the type of the argument for the driveCar function, thus, is unable to know that the drive method is used (or unused in case c is not actually instance of Car) and thus it is unable to determine if the drive method should be removed or not.

I was also pointed out that this kind of code modifications are outside the scope of the project. I can understand and accept that. But consider how much one could save from a DOM access library if all code related to ajax is stripped, should ajax is not required, or promise related, or pub/sub related code can be removed from the resulting build should it not be used.I would argue that while this might not seem like a lot, getting built code that contains only the instruction that you actually use is much better than containing all possible instructions in all used pieces of code.

Now for number one: Closure is compared to UglifyJS in simple mode.
Well, of course it is slower, it is written in java! And of course closure cannot compile all your libraries, it is written to compile applications, not libraries for third party use ( however at google they use it for this too!). Using the compiler in advanced mode will most often break your code, this is why there are some code style rules to be followed should the compiler is to be used in that mode. The gains are significant, but the friction is so much, most developers just do not bother. For one, you cannot just stop any library in your project path and expect it to work. This is a big show stopper for most developers. Then you also need to write your code in google's funny way of name spaces. You are forced to use only a few subset of JS patterns ( no matter how memory and efficiency optimized those are - limits are limits).

So next time you evaluate the two options, please make note of the difference between minification and 'compilation'. While it is not a real compilation, the code changes made are much greater than method and property renaming.


Няма коментари: