Combine, Minify, And Compress Your JavaScript

Writing

It pretty much goes without saying that if you are building a public facing website these days you are probably using a ridiculous amount of JavaScript. And it is also likely that most of the JavaScript is in the form of libraries that you didn’t write and you don’t maintain. But even if you aren’t maintaining those libraries, you are still responsible for pushing them all down to your users. And so you can get into the situation where you have either hundreds of kilobytes of JavaScript or you just end up with a ton of tiny script files. Both of these can really put a damper on the amount of time that your site initially loads for your user.

Fortunately for us there are several solutions to the problem of slow loading JavaScript. One is to try and load most of your libraries from content delivery networks (CDN) provided by companies like Google and Microsoft. A second is to employ a CDN of your own like Amazon’s CloudFront. But no matter what you are doing to speed up your the delivery of your JavaScript, it is absolutely imperative that you do three things:

  1. Combine your JavaScript files: Concatenate all of your JavaScript files into a single file so that the browser only has to make one request to download your scripts.
  2. Minify your JavaScript files: Perform some optimizations on your JavaScript to remove whitespace, shorten variable names, and in some instances even perform some static analysis to optimize statements or  remove unused code.
  3. Compress your JavaScript: Enabled gzip compression so that users that have browsers which support compression will receive a smaller file.

Now this may sound like a lot of work, but thankfully people like my friend Dave Ward have already solved the problem of easily combining and minifying our JavaScript files in a pretty easy way. However, I was looking at one of my favorite JavaScript libraries, SyntaxHighlighter, and I was thinking that it was just an absolutely huge amount of files that you had to import in order to use it. SyntaxHighlighter has hosted versions of its files, and so wouldn’t it be cool if I could just pull those hosted versions, along with my other javascript and then combine, minify, and then just push all of that up to my CDN?

So I started thinking, wouldn’t it be useful if I just had a utility that I could pull into my projects which would give me a way to pull in single javascript files, directories, urls and then combine, minify, and even compress those files? Yes, of course that would be cool! And since I was pretty much snowed in on Saturday, I set out to create this little utility that I call JavaScript Bundler. Pretty clever name, huh?

So what features does JavaScript Bundler have currently?

  1. It can pull in any number of JavaScript files by specifying their names.
  2. It can pull in entire directories of JavaScript files by specifying the directory. You can also put a ordering.txt file in the directory which will contain a list of the file names in the order that you want them concatenated. Remember, ordering can be important when you are importing JavaScript!
  3. It can pull in JavaScript files from urls, so if you had a library which was hosted somewhere that you wanted to pull in, you can easily do so.
  4. You can pull in any combination of the above three file types and combine and compress them into the same file.
  5. You can optionally minify the combined JavaScript using either jsmin or Google’s Closure compiler. The YUI Compressor is currently included in the project, but has not been implemented. I am open to implementing other minifiers/compressors as well.
  6. You can optionally output pre-gzipped versions of your files in case you are using a CDN which does not support gzipping files natively. This way you can direct users to the gzipped files if their browser supports it.

Let’s take a look real quick at how it works. First, we can access the JavaScript Bundler’s help by passing "/h" (if you’re wondering what I am using for parsing command line parameters, well, that is the wonderful Mono.Options library which is written by my friend Jonathan Pryor):

 jsbundler command line options

Now you can see that if we want to specify a single JavaScript file to include, we just pass it using the "–file=" parameter and then we can specify the output via the "–out=" parameter. It would end up looking like this:

 image

This would actually just output the contents of myfile.js into combinedfile.js because we aren’t specifying a tool with which to perform the minification. If we wanted to use jsmin we could specify it by passing the "–min=" parameter:

image

And if we wanted to pull in a file, a directory, a url, and then compress all of it using the Google Closure compiler (which requires Java to be installed and on the path) we could do this:

image

And remember, when we pull in that directory we might want to specify the order in which we concatenate the files. We can do this by adding a file called ordering.txt and placing it in the directory. It might look something like this:

image

Overall I’d like to keep this utility fairly simple, and with a few minor exceptions it already fills the needs that I set out to fill. So, what are those exceptions, what features do I want to add to it?

  1. More console output (with quiet option). It doesn’t really tell you what it is doing currently.
  2. Error handling. It doesn’t really check much right now.
  3. Ability to specify file masks when pulling in a directory.
  4. Use a config file to specify files, compression methods, etc… instead of passing items as command line parameters. I think this would give a bit more flexibility.
  5. Implement the YUI Compressor.
  6. Combine and compress css files as well.
  7. Maybe have an option to pull in standard libraries. Not sure how to work this out with versioning though.
  8. Anything great ideas that you guys have!

I hope that if you get a chance you’ll check it out and let me know what you think. Also, if you have any great ideas for changes to make, or you want to help out, please leave a comment! Thanks!

Download v0.1 of the JavaScript Bundler and if you want the (super ugly) source just grab it from the JavaScript Bundler repository over on GitHub.

More Insights

View All