I've been working a bunch with JavaScript over the last few weeks, building a number of library type components that have script dependencies. I'm still bouncing back and forth between the idea of using embedded Resources with ASP.NET (ie. WebResource.axd) a compressed resources using a custom Script Compression module I posted some time ago, or just using plain old .js files in a designated directory and serving them from there.

If I end up serving disk based JavaScript Resources I want to compress these resources and I've taken over the jQuery common approach of using a main file with a .js extension and also a compressed version with .min.js. These compressed files remove all whitespace and comments from JavaScript files thus reducing the size of the JavaScript by about 30%-40% on average. The good news about this is that you can be more verbose in your JavaScript code and reduce the size. This ratio holds even if you (or the Web Server) add GZIP compression ontop of the minimized module.

There are lots of tools out there for compressing JavaScript, some online etc. In fact, I'd been using Dan Wahlin's Java Script string compression utility for a while to do conversions manually, but I wanted something that I can use right in my VS project as an Open With option and that can directly compress files on disk as well as strings and do batch conversions.

So I created a quick and dirty utility that does the job using Douglas Crockfords JavaScript Minifier (which is also what Dan used) and wrapped it with a small WinForms app that can also run via Command Line and do batch conversions. I also made a few modifications to the original compression class to support string to string conversion so it can also be used for things like my script compression module.

The resulting WinForms app looks like this:

You can use this app either as a ClickOnce Application online or by downloading the tool and source code (.NET 2.0 required):

The tool supports using wildcards so it can automatically pack all .js files in a given directory in batch by using *.js for the filename. If the output filename is not specified the output files are assumed to be created with a .min.js extension.

You can also use this tool via the command line:

jsMinifier.exe [InputFile] [OutputFile] [NoUI]

The output file is optional and if not specified defaults to the same name as the input file (or files if *.js is used for the filenames) with a .min.js extension. In batch conversions you can specify an alternate extension by using .compressed.js for the output file for example (ie. without any sort of filename - just the output extension). NoUI can be used as the second or third parameter to specify command line only operation. Otherwise the WinForm is displayed with default values set.

I liketo use it from within Visual Studio interactively, so I've got it tied to the Open With menu:

Which makes short work of updating JavaScript files. If you want a more automated approach you can also add a post build task to do the conversions automatically say in the Release build only.

Script Compression

As I mentioned the compression provided by this routine tends to cut roughly 30-40% of most of the script files I've thrown at it, depending how terse the code is. The key advantage is that whitespace and comments are stripped so if you're coding JavaScript you don't have to count bytes for simple formatting like I've been doing often in the past with some of my library code.

I tend to use this with the assumption that every java script file I load in a library has both uncompressed and compressed versions available and so the library/component code trying to load resources in Debug mode will  use the uncompressed version and the compressed version when running in release build which works well and can get some of the same benefits that a dynamic Web Resource approach can offer.

I'm still debating what works better - using Web Resources or external files. I'm leaning more towards the Web Resource approach whenever possible because it give you as the developer more control, but recently when I posted the  jQuery Calandar ASP.NET component several folks commented that they thought it a bad idea to stick script resources into an ASP.NET assembly. I don't fully agree but I do see the point regarding potential resource and version conflicts, so I pretty much came to the conclusion that it's best to always provide explicit URLs for all resources and having them default to an embedded Web Resource that can be overridden as needed (or be omitted altogether if it's already loaded). And that's where this sort of pre-compression comes in. I think even in combination with GZIP it's still worth it to trim off the fat as it were especially if we want to code JavaScript that is actually readable and not trying to eek out every last byte in favor of size <g>...