12 April 2008
With rich internet applications being all the buzz these days people are finding themselves pouring more and more interactivity onto their pages. Typically, this is if nothing else through a slew of external third party libraries, or as with Dojo and Scriptaculous and YUI, entire frameworks! Taken one at a time these various scripts – used sparingly and perhaps compressed – don't cause too much a burden on your server or the client during download. Right...
So say you build up a complex layout / widget set for your site. Say that you're also consistently using prototype.js and rico.js and a few of the scriptaculous libraries and that you've also got a few other 'commodity' scripts that are used everywhere (company libraries, a widget built on prototype, etc, etc). Anything. Now you've got 6 different .js files to include on every page, and you haven't even STARTED loading your code – you remember that code, right? The code that actually does the line of business you set out to help with this application in the first place? All these HTTP requests are bad for the server, but they're also really bad for the client. Load enough scripts and eventually things to start to deteriorate, even crash, on the client.
My definition of an ideal solution would be something that knew how to combine multiple libraries into one, compact that code except where the resulting source code would be made un runnable – and that conditionally served gzip content.
Enter JAWR, a library freely available from https://jawr.dev.java.net/ that does all of the above. It even can work its magic on .css files! It provides tag libraries (accessible from both JSP and now –with the 2.0 release – from Facelets). I'm sure if you were so inclined you could reverse engineer the tag library handlers and wrap it in a Tapestry component or a Wicket widget.
Below, I walk through setting up a simple example:
For my example, I'm using JSF and Maven. Set up the web application however you like. If you're using Maven, here is the dependency I'm using:
Ensure that you have the following repository added to Maven:
<name>Java.net Repository for Maven</name>
<param-value>js</param-value> <!-- this could be css -->
<!-- Location in classpath of the config file -->
The above configuration requires the presence of a file named jawr.properties on the classpath.
# Common properties
jawr.js.bundle.names=appcore,railsjs# All files within /js/lib will be together in a bundle.
# The remaining scripts will be served sepparately.jawr.js.bundle.effects.id=/bundles/effects.js
The configuration format is somewhat akin to editing a log4j.properties property file.
var a = 1
var b = 2 ;
window.alert( 'a = ' + a + ' & b = ' + b ) ;
var a = 1
var b = 2 ; window.alert( 'a = ' + a + ' & b = ' + b ) ;
Pretty cool, eh?
So, in the example above, I tell JAWR to create two "bundles":