Decrease your pages load time
Web applications have several advantages over traditional client server applications: since business code comes from a unique server (forget clustering here), they are always up-to-date. Moreover, deployment of a new version is only a matter of minutes.
They have one big drawback, though. Since HTML code is sent through the network, responsiveness is generally much less than that of traditional applications.
The responsiveness of an interactive system describes how quickly it responds to user input (i.e. the rate of communication with the system).
Ajax overcomes some of this in proposing to load the entire page at start and the modifiying pertinent chuncks of it. Yet, it is only part of the solution, since initial loading of the page will be the hardest on the user. Users don’t like waiting for a page to load. As a user, you don’t like waiting. As a good rule of thumb, you must make every effort to achieve a initial page load time of less than 1 second (you can find additional informations on load time steps in this very interesting article). This load time doesn’t cover the time for the entire page and style sheets and scripts to finish downloading, but only the time for the user to have pertinent informations displayed and to begin interacting with the screen. This is of cours very context dependent but conclusion is: the less time your page takes to display, the better it is.
2. Decreasing load time
Yahoo provides 34 best practices to speed up your site. If you use Mozilla Firefox, and you already use the fantastic FireBug plug-in, you should add the YSlow plugin to it (if not, download FireBug beforehand). YSlow checks the web page you’re browsing with Firefox for 13 of these rules. The important rules for the matter at hand are:
- Make JS and CSS external,
- Make fewer HTTP requests,
- Minify JS (and CSS).
3. Minification at build time
Among all the tools avalaible, a good one for minifying JS and CSS (starting from v2.0) is Yahoo UI Library Compressor. It is developed in Java and can be runned from the command line. Such command can take place during the build process. The following Ant task executes the minifying process on simple.js :
The main drawback of this solution is that you lose your original script in favor of the minified one. YUI compressor enables to output the minified script in a new script, hence the following Ant target :
This makes the process slightly better. Yet, I cannot test the minified script under my favourite IDE because the script is only correct in the WAR creation scope, not in the deploy-in-IDE scope.
4. Minification at runtime
In order to prevent this drawback, we could make the minifying a runtime process. In order to do this, we create a filter that is associated with .js extensions :
Now our compressor works both in and out of our favorite IDE. But the drawback is the performance lost in applying the filter each time the resource is needed. In order to lessen this cost, we could:
- implement a cache that maps paths to minified scripts (as strings) in memory,
- rely on the browser cache by using HTTP headers related to expiration values.
Still, I find this not very satisfying… First of all, YUI compressor was not supposed to be used in this fashion. This shows because you find no documentation, JavaDoc or else, regarding individual use of the methods. Then, the less I code, the better I feel. In this case, I had to code a whole filter, complete with initialization parameter. Last but not least, do you remember the 3 rules, at the top of the article? We adressed only the 3rd point, minifying the script, but in no way did we make fewer HTTP request by using YUI compressor. If we had 15 different source scripts, we would still have 15 minified scripts at the end and thus need 15 HTTP requests to get them all.
Jawr is the solution to our problem: it enables to have different scripts during development (third-party scripts, enterprise framework scripts, applications scripts, etc.) and bundles them at application startup in one big script file. The process is completely transparent to the developer and is lightweight because all work is done at application startup.
Additional features include:
- Modifying those files dynamically, e.g. with
- Caching enforcement through is a modification of sent HTTP headers,
- GZip support for compatible browsers.
In order to do so, Jawr uses 3 kind of components:
- jawr taglibs that references JS and CSS,
- a configuration file in Java properties format.
The configuration of the web deployment descriptor will look something like this:
JawrServlet net.jawr.web.servlet.JawrServlet configLocation /jawr.properties 1 JawrServlet *.js
An example properties file will look like this
#Turning on compression when possible jawr.gzip.on=true #Using YUI compressor jawr.js.bundle.factory.bundlepostprocessors=YUI #Bundling into all.js jawr.js.bundle.all.id=/script/all.js #Bundled scripts jawr.js.bundle.all.mappings=/script/simple.js, /script/sub/b.js, /script/sub/subsub/a.js
The, you will use it like this in your page:
<%@ taglib prefix="jawr" uri="http://jawr.net/tags"%>
You will find there a Jawr example project made with Eclipse along with the previous YUI Compressor example. This example shows you the main uses of Jawr, mainly:
- minifying them,
- compressing the bundled file (if you browser supports it).
Minifying external files is not the only think of in order to decrease your web pages load time. You should also decrease to the maximum the number of these files. Jawr is an OpenSource component used to do both elegantly: I hope this article convinced you that Jawr is the right tool for this usage.