Javascript compression filter

Yesterday a colleague asked me whether it is possible to automate compression of javascript code in a web application (the current project has a total of about 150kb of javascript for some of the pages). I decided to look into the issue a bit...

There are tons of offline javascript compressors/obfuscators etc. but the ones using Rhino seem to be among the best. This is mostly due to the fact that Rhino can fully interpret the code and decide whether, for instance, variables are local or not. Another good feature of Rhino is the fact that it is java based. The Dojo toolkit offers a patched version of the Rhino library which can be used safely to compres javascript offline.

I couldn't find inline (filter based) compressors... so I decided to wrap the Dojo Rhino version in a filter. Took some work to figure out how Rhino is used, but I managed to get everything to work.

Instead of pasting code here I decided to install a subversion repository, it is browseable through the web from the following URL:

http://svn.maas-frensch.com/pmutils/javascript_compressor_filter/trunk/

The project contains a minimal webapp demonstrating the use of the filter, a simple build file (be sure to configure your tomcat base-dir for compiling) and can be checked out anonymously.

If you just want to use the filter download the following files and put them in your WEB-INF/lib folder (compiled for java5!):

and add the following lines to your web.xml descriptor:

XML:
  1. <filter>
  2.   <filter-name>javascript compressor</filter-name>
  3.   <filter-class>com.finalist.web.filters.JavascriptCompressorFilter</filter-class>
  4. </filter>
  5.    
  6. <filter-mapping>
  7.   <filter-name>javascript compressor</filter-name>
  8.   <url-pattern>*.js</url-pattern>
  9. </filter-mapping>

I've tested the filter on my current, Javascript heavy project and it manages to reduce the filesizes by about 50%.. and they still work! Also it's now safe to fully document 'unwanted' but known behaviour of javascripts without the risk of accidenlty exposing it to external users.

The following example illustrates the working of the filter:

input

JavaScript:
  1. /**
  2. * called when the window is finished loading
  3. * registers hanlers to each 'anchor' with classname 'button'
  4. */
  5. window.onload = function(){
  6.   var anchor = document.getElementsByTagName('A');
  7.   for(var i in anchor){
  8.     if(anchor[i].className == 'button'){ // if A has class button, register event handlers
  9.       anchor[i].onmouseover = over;
  10.       anchor[i].onmouseout = out;
  11.       preload(anchor[i]); // preload images
  12.       anchor[i].style.backgroundImage = "url('"+anchor[i].getAttribute('out')+"')"; // set default image
  13.     }
  14.   }
  15. }

output:

JavaScript:
  1. window.onload=function(){
  2. var _1=document.getElementsByTagName("A");
  3. for(var i in _1){
  4. if(_1[i].className=="button"){
  5. _1[i].onmouseover=over;
  6. _1[i].onmouseout=out;
  7. preload(_1[i]);
  8. _1[i].style.backgroundImage="url('"+_1[i].getAttribute("out")+"')";
  9. }
  10. }
  11. };

After writing the filter I discovered DWR has some java based compression utilities as well; and it is allready on the project classpath. Maybe I'll expand the filter with configuration options for selecting the compressor to use.


2 Responses to “Javascript compression filter”

  1. 1 erikvanoosten

    Interesting.
    You're suggesting that comments are removed from the compressed output? Could you add that to the example?

  2. 2 peter

    I replaced the example, this one should be a bit clearer. As you can see, all comments are stripped and local variables are renamed.... next to the more obvious removal of whitespace.

Leave a Reply





About

Welcome to the weblog of Peter Maas. Here you'll find various posts related to stuff I like (like my kids and espresso) and stuff I do (like developing software).

JavaOne 2008 Pictures


Stage being build in the nearby park Tim Bray introducing the (J)Ruby panel Greenland alcatraz Acme Anvile at CommunityOne Keynote golden_gate_warning_sign pub Moscone Center - JavaOne sea_lion Rudie Golden Gate Scribbled Sun Logo Joshua Bloch at JavaOne2008 Hotel room Stretched Limo Community One Keynote Cable Car line Java + You on a cab nearby hotel Okke en Rudie
View more photos >

Categories



Meld u aan voor PayPal en begin direct met het accepteren van creditcardbetalingen.