18 Jan 2010

Yahoo YUI Compressor vs. Microsoft AJAX Minifier vs. Google Closure Compiler

13 Comments Uncategorized

A little more than a year and half ago I created a MSBuild Task for the YUI Compressor that was very well received, and even highlighted on the YUI Compressor site.  At the time of writing that article YUI Compressor was king of the hill, and for the most part the only game in town that was really designed for production level use.  Since then a number of new competitors have been released by Google and Microsoft, and I wanted to see how they stacked up against the YUI Compressor.

Setup

For these tests I wanted to test a pretty complex set of JavaScript to really stretch the limits of each of the optimizers. So I choose jQuery 1.4 as the subject for the tests.  I choose jQuery for many reasons, but the biggest is because it is very well known set of code for most developers, and it would be very easy for anybody to test in their applications.

The setup of my machine is as follows:

  • Windows 7 Pro (x64)
  • Java 6 Update 17
  • .NET 3.5 SP1

Each optimizer and the version:

Testing

I ran the following from the command line on jQuery 1.4 raw source code to produce the following files.  Here is the raw source code file that I used in my testing:

Microsoft
ajaxmin jquery-1.4.js -o microsoft.js
Microsoft (Hypercrunch)
ajaxmin -h jquery-1.4.js -o microsoft-h.js
Microsoft (Hypercrunch Combine Literals)
ajaxmin -hl jquery-1.4.js -o microsoft-hc.js
Google (Whitespace)
java -jar compiler.jar --compilation_level WHITESPACE_ONLY --js jquery-1.4.js
Google (Simple)
java -jar compiler.jar --compilation_level SIMPLE_OPTIMIZATIONS --js jquery-1.4.js
Google (Advanced)
java -jar compiler.jar --compilation_level ADVANCED_OPTIMIZATIONS --js jquery-1.4.js
Yahoo
java -jar yuicompressor-2.4.2.jar jquery-1.4.js -o yahoo.js
Yahoo (Minified Only)
java -jar yuicompressor-2.4.2.jar jquery-1.4.js --nomunge -o yahoo-m.js
Yahoo (Disabled Optimizations)
java -jar yuicompressor-2.4.2.jar jquery-1.4.js --disabled-optimizations -o yahoo-o.js
Yahoo (Preserve Unnecessary Semicolons)

java -jar yuicompressor-2.4.2.jar jquery-1.4.js --preserve-semi -o yahoo-s.js

Results

The above testing produced the following results.

  Size (bytes) Command Options Size Optimization Place
jQuery 158407   100.0000%
Microsoft 93814   59.2234% 8
Microsoft (Hypercrunch) 70156   -h 44.2884% 4
Microsoft (Hypercrunch Combine Literals) 67149   -hc 42.3902% 2
Google (Whitespace) 94225   –compilation_level WHITESPACE_ONLY 59.4829% 9
Google (Simple) 69467   –compilation_level SIMPLE_OPTIMIZATIONS 43.8535% 3
Google (Advanced) 63384   –compilation_level ADVANCED_OPTIMIZATIONS 40.0134% 1
Yahoo 76453   48.2636% 5
Yahoo (Minify Only) 94843   –nomunge 59.8730% 10
Yahoo (Disabled Optimizations) 76465   –disable-optimizations 48.2712% 6
Yahoo (Preserve Unnecessary Semicolons) 77384   –preserve-semi 48.8514% 7

The results are pretty clear of who won the top prizes in the above results.  Out of the top 5 ranking outputs Google and Microsoft both took two of the positions and Yahoo took 1. Google Closure Compiler placed first when the Advanced Options were enabled which did really surprise me that much, and Microsoft AJAX Minifier placed second when Hypercrunch and Combine Literals were turned on.  The Microsoft ranking, however was very surprising to me because of the lack-luster reviews of RC6 that was released back in October.

There are a couple things that should be noted about Google Closure with Advanced Options, which may not make the most beneficial option for you to choose when you are trying to minify your files.

  1. Removal of Code You Want to Keep
  2. Inconsistent Property Names
  3. Compiling Two Portions of Code Separately
  4. Broken References between Compiled and Uncompiled Code

Because of how the file is being optimized, it alters your code and would require you to do extra testing before deployment and it would make the resulting output almost impossible to debug against your un-minified version.  So for these reasons it may not be the best choice, if you value ease of testing over byte size of your files.

So which ever option out of Microsoft, Google, or Yahoo you decide to use, all will produce a much more optimized-for-size file than the original. And, in my opinion, if you are already using Yahoo in your build environment there really isn’t much of a reason to switch, unless you are in the top tier of websites and need to squeeze every byte out of the file for delivery over the internet.

Personally, I am going to keep using YUI Compressor, because it has been rock solid in producing minimized and obfuscated code for my current projects, but in the future I may consider going with Microsoft or Google depending on what I am trying to accomplish.

08 Dec 2008

Creating a Progressive Queue in IE6 JavaScript

No Comments Uncategorized

Today IE6 really kicked my butt, I had the following code working in FireFox, IE7, etc, all except IE6:

ShowLoadingPanel();
// execute some code here
HideLoadingPanel();

The above code is really simple, it shows a full screen loading panel when I am executing some code in between the Show and Hide functions for the loading panel. It worked in every browser that I tried except for IE6. This seemed to occur because the execution of the JavaScript was happening in the same thread as the UI rendering of the screen, which would block all screen updates to the browser until the JavaScript was executed. By the time all the JavaScript is done rendering the UI is in it’s final visual state, so it looks like the loading graphic was never run. Note I don’t know for sure that this is what is really happening, but it definitely seems like the most likely possibility. But if this is true it really explains the lack of support for JavaScript Animation, which heavily relies on a progressive incremental rendering of the UI.

On my way back home from work after dealing with this for a while, a light bulb clicked on in my head and it occurred to me. That I might be able to use the setTimeout function to force the execution in to a different thread, which would free up the current thread to render the loading screen.

ShowLoadingPanel();
setTimeout(function() {
    // execute some code here
    HideLoadingPanel();
}, 500);

Basically what the above is doing is creating a slight delay in the execution of the code. Which releases the current thread to render the loading screen to the browser. After that is done the rest of the code, in the setTimeout, is executed in the background and locking up a different thread. The important thing to remember is to keep the method that hides the loading panel inside the setTimeout so that the hide panel method is executed in a different process and after the code that you want to execute.

So that is how you create a progressive queue in IE6 for JavaScript. Until next time I hope you found this useful.

11 Oct 2008

Add Your Twitter Status To Your Blog

7 Comments Uncategorized

For the longest time I have been wanting to add my Twitter status to my blog in place of my quote right under my blogs name in the header.  (see above)  Today I sat down and figured out what I needed to do to accomplish this and to my surprise it only took all of 10 minutes to complete.

What you need in order to achieve the same for your own blog is:

  1. Managed Fusion Url Rewriter and Reverse Proxy
    This is used to get around cross site scripting blocks that modern browsers impose on JavaScript.  It is used to create a proxy from a local URL to an external URL by fooling the browser in to thinking it is requesting the feed locally.
  2. jQuery
    This is my favorite JavaScript framework, you can use your own, but my examples will be in jQuery.

The first thing you need to do is add a defined spot in your blog where you want the jQuery to write your twitter text status to. I created the following tag in my blog that has an ID of “twitter-status”, the inside of this tag will be replaced with whatever status is downloaded from twitter.

<span><a href="http://www.twitter.com/nberardi">twitter status:</a>&nbsp;<q cite="http://www.twitter.com/nberardi" id="twitter-status">status loading...</q></span>

The second thing you need to do is add a RewriteRule to the rewriter rules for a reverse proxy to the Twitter API. The rewriter rule that I used is:

# get twitter status
RewriteRule ^/twitter-status\.(.*) http://twitter.com/users/show/nberardi.$1 [NC,P]

So if you go to http://www.coderjournal.com/twitter-status.xml, you will get the direct feed that comes from http://twitter.com/users/show/nberardi.xml.

The third and last thing you need to do is add the jQuery JavaScript to the bottom of the page right above the </html>. What this script does is make a GET request to the URL that I defined above and downloads the content as JSON, which creates an object so that it can be used by JavaScript.

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js"></script>
<script type="text/javascript">
    $.getJSON(
        "/twitter-status.json",
        { },
        // on successful call back
        function (data, textStatus) {
            $("#twitter-status").text(data.status.text);
        }
    );
</script>

So it was really that easy. And it can be done for any feed that you want to pull from anywhere on the internet, it just happened to be that in this case I wanted to grab a feed from twitter.