Compressing JavaScript … TO THE MAX!
Here is the best recipe I've came up with so far to compress JavaScript. The goal here is to get our JavaScript file the smallest possible. In a nutshell, first we will obfuscate and then we "minify" it.
With obfuscation we'll convert all of our meaningless variables to the shortest meaningful variable needed. "Huh?" What I mean by that is basically all of our variables that we don't have access to or need, specifically variables within functions don't really need any meaning as long as they get the job done... per se... When we write code we name variables in a way so that they make sense to us, humans. There's obviously nothing wrong with that but on the computer's side of things they're just a set of instructions where the naming doesn't mean anything. totalPrice + tax = price means the same to a computer as foo + bar = result which means the same as _1 + _2 = X. We're going to use obfuscation to save space of our useless variable names.
Clarification: The variables aren't useless, their long names are.
After doing what we can with variables we then need to minify our script. This is very simple, just removing all useless white-space and line breaks. It may not sound like much but your web browser would also have an easier time parsing your code if it was all on one line.
The tools for the job
And walla! Go ahead and download these tools off their sites. For JSMin just download the C source code for now if you're on Mac or *nix but if you're on Windows they should have a zip file containing an .exe on the bottom of the page somewhere. For the prior, simply compile the source like so:
$ gcc -o jsmin jsmin.c
- Custom Rhino: This is what we'll use to obfuscate our JavaScript code. Custom Rhino is a modified version of Mozilla's Rhino JavaScript interpretor which has an obfuscation feature added to it.
- JSMin: And this would obviously be our minify tool! There are actually quite a few other tools that do the same thing JSMin does but I chose to use JSMin because its available in many programming languages. This is a plus for me because I love getting my hands dirty in other languages and it just works.
Doing It!
Lets get started with our ever so boring Hello World! test but because this project is so exciting it will make up for it! Right? Hehe anyways here goes our little JavaScript code, put this and the programs we've downloaded above all into one directory just for the sake of testing for now (you can organize them into somewhere more meaningful later) and save the JavaScript code as test.js:
var message = "Hello Richard!"; helloWorld = function(msg) { var message = msg.toUpperCase(); alert(message); } helloWorld(message);
Very simple. We got a global variable named message, and function named helloWorld. Now its time to pack this baby together! Open up a console window and lets do it step by step:
$ java -jar custom_rhino.jar -strict -1 -opt -c test.js > tmp.js
If you take a peek at tmp.js then Rhino should have generated this:
var message="Hello Richard!"; helloWorld=function(_1){ var _2=_1.toUpperCase(); alert(_2); }; helloWorld(message);
What's really important to note here is that our global variable names remained the same and so did our function. The only code that is obfuscated is the code that means nothing to us anyways
... Nothing in that we don't access it anyways.
Next we minify the code with JSMin:
$ ./jsmin < tmp.js > test_compressed.js
Our code should look like:
var message="Hello Richard!";helloWorld=function(_1){var _2=_1.toUpperCase();alert(_2);};helloWorld(message);
And walla! Isn't that beautiful! Of course the space savings isn't tremendous with this small script but I've tested it with Prototype v1.6.0.2 and it went from 123kb to 83kb! That's about a ~40% save right? Not so bad.
So now we've got our code obfuscated and compressed on the client end as much as possible. This should definitely help with transferring over all your JavaScript much faster and your browser should have an better time rendering it.
We can also eliminate the need for tmp.js and perform the above operation with one command:
$ java -jar custom_rhino.jar -strict -opt -1 -c test.js | ./jsmin > test_compressed.js
Conclusion
Well there you have it. Its also good to note to always start and end loops and conditions with opening and closing brackets even if you have those one liners for compatibilities sake. Your code should be packed for distribution when you are sure its at a stable state otherwise debugging can be problem and a headache fast.
If you want to take things further you can optimize your server end by adding gzip compression to Apache or whatever you use and also refactoring your code. The lesser try/catches would help as well.
Here are a few other tools:
- Dojo Shrinksafe: An online compression tool made with Dojo's custom_rhino.jar.
- Rhino: This is the homepage of the Rhino JavaScript interpreter that the Dojo developers extended to give obfuscation capabilities to.
- Dean Edwards Packer: A pretty popular JavaScript packer. Source also available
- Packer JavaScript in PHP: Same as the one above but made in PHP
July 12th, 2008 at 2:32 am
I read similar article also named Compressing JavaScript … TO THE MAX!, and it was completely different. Personally, I agree with you more, because this article makes a little bit more sense for me