Is there a need for a new JavaScript minifier?
According to Yahoo!’s Exceptional Performance Team, 40% to 60% of Yahoo!’s users have an empty cache experience and about 20% of all page views are done with an empty cache (see this article for more information on browser cache usage) This fact outlines the importance of keeping web pages as lightweight as possible. Improving the engineering design of a page or a web application usually yields the biggest savings. After that come many different techniques such as minification of the code, HTTP compression, etc. In terms of code minification, the most widely used tools to minify JavaScript code are Douglas Crockford’s JSMin and the Dojo compressor. Both tools however have pitfalls. JSMin, for example, does not yield optimal savings (due to its simple algorithm, it must leave many line feed characters in the code in order not to introduce any new bugs) The Dojo compressor, on the other hand, does a better job at compacting code (it obfuscates local variables) but is unsafe and potentially introduces bugs if you are unaware of its limitations.
What is the YUI Compressor?
The YUI Compressor is a new JavaScript minifier. Its level of compaction is higher than the Dojo compressor, and it is as safe as JSMin. Tests on the YUI library have shown savings of about 18% compared to JSMin and 10% compared to the Dojo compressor (these respectively become 10% and 5% after HTTP compression)
How does it work?
The YUI Compressor is written in Java (requires Java >= 1.4) and relies on Rhino to tokenize the source JavaScript file. It starts by analyzing the source JavaScript file to understand how it is structured. It then prints out the token stream, replacing all local symbols by a 1 (or 2, or 3) letter symbol wherever such a substitution is appropriate (in the face of evil features such as eval
or with
, the YUI Compressor takes a defensive approach by not obfuscating any of the scopes containing the evil statement). The YUI Compressor is open-source, so don’t hesitate to look at the code to understand exactly how it works.
Where can I get it?
An archive containing both source and binary is available for download on this site.
How do I run it?
java -jar yuicompressor-1.0.jar
[-h, --help] [--warn] [--nomunge]
[--charset character-set] [-o outfile] infile
The following command line for example:
java -jar yuicompressor-1.0.jar myfile.js
will minify the file myfile.js
and output the file myfile-min.js
. For more information on how to use the YUI Compressor, please refer to the documentation included in the archive.
Limitations
Unlike JSMin, the YUI Compressor is slow and cannot be used for on-the-fly code minification (see minify for a PHP implementation of JSMin by Ryan Grove, another Yahoo! engineer, that does on-the-fly JavaScript minification among other things)
Has Yahoo!’s official position on obfuscation changed?
Douglas Crockford wrote an interesting article last year on minification vs. obfuscation. While that article still holds true, the YUI Compressor actually represents a 3rd way, in which code compaction does not carry the risk of introducing new bugs. The YUI Compressor is currently considered as a replacement for JSMin to compact the entire YUI library.
Feedback appreciated
The YUI Compressor is still a fairly new tool, so your feedback is well appreciated. Don’t hesitate to drop me a line if you find a bug, or think an important feature is missing. I will make updates available on this site, so watch for posts related to the YUI Compressor on this blog. This software belongs to the community, so it’s up to the community to make it better!
Additional notes
- Do not hesitate to use the
--warn
option. The YUI Compressor will warn you if it finds anything that seems abnormal with your code, or that might reduce the level of compression.
- Keep as little of your code as possible in the global scope. This has 2 benefits:
- You’ll get a better level of compression since the YUI Compressor does not obfuscate global symbols (which would make it unsafe)
- You won’t pollute the global object (see this article)