Lets say you have a web application that uses some YUI widgets and also some other commercial AJAX widgets. Now these frameworks contains many .js and .css files that need to come down to the browser. To add to this mix you have your own javascript files. Caching these files in the browsers’ cache will help performance and give the user a better experience. Also since some of these files are quite large we can consider gzipping them on the server to reduce the payload size.
To get to this analysis I used Yslow Firefox plugin (http://developer.yahoo.com/yslow/). It analyzes the current page and gives it a grade. The application I tested did not get grade ‘A’ but I cannot control the remaining items (such as CDN). I would strongly recommend folks to use Yslow to at least see where things stand. Also check out http://developer.yahoo.com/performance/rules.html.
First things, I need to cache .js and .css files in the browser cache. I was using Weblogic 8.1 and could not find a configurable way to set expires headers for .js files that are included like:
<script type=”text/javascript” src=”<%=context%>/js/yui/<%=yuiVrsn%>/yahoo-dom-event/yahoo-dom-event.js”></script>
<script type=”text/javascript” src=”<%=context%>/js/myapp.js?<%=bldVrsn%>”></script>
I put in a version as part of the URL since I do not want to be at the mercy of the users browser settings. If I change the YUI version on the server then it will force the browser to pull down the new file and NOT use any old cached version with the same file name. I follow the same approach for 3rd party files as well as my own (with my own files I use a build version).
If you are using Apache Web Server then there are configuration parameters you can setup to control cache headers and gzipping (using mod_gzip). I could not find a configurable approach in Weblogic 8.1. Either it is hidden deep inside or it just does not exist.
So instead I put in a couple of Servlet filters to do the job for me. First one is a custom servlet filter that is mapped to all .js and .css files. This one simply adds an Expires header with 30 days into the future. I can do 30 days since I know I have control of the URL via version numbers. The second filter is for gzip. I was about to create my own filter when I noticed a gzip filter inside ehcache (net.sf.ehcache.constructs.web.filter.GzipFilter). I looked at the source and it did what I needed so I used it. The main thing that this filter does is to check the ‘Accept-Encoding’ header in the request to make sure that the client can support gzip and then if that’s good uses the java gzip libraries to compress the contents.
One other thing Yslow reported was to reduce the number of .js files. With framework files such as YUI I cannot control that, but with my own libraries I can. I did merge some utility scripts into a single file. Not a big difference in the end but that’s what tuning is. Getting a little here and there and the grand total adds up fast.
If there are other ways folks have implemented this then please let me know. Remember I am own Weblogic 8.1.