Posts Tagged ‘jawr’
  • Decrease your pages load time, one year later

    More than one year ago, I blogged about pages load time and Jawr. Since then, either my projects were intranet applications where load time was not an issue or we had no say in the tools used. So, I had no possibility to use any of the tools I found then. Now, I’m soon to be faced by an application that will be used by people outside our network and I definitely want the application to be as responsive as possible. Armed with my previous Yahoo best practices, I hunted on the web for tools that could help me enforce them.

    One rule I hold in high esteem is: minimize the number of HTTP requests. I think this rule has the most impact since browsers only send at most 2 HTTP requests at a time. Let’s take a classical example. Buttons play a big part in many applications and most of the time, you put an icon on them in order to tie them to the action in the user’s mind. This is simply done like so:

    <button><img src="path/to/my/image" />Label</button>

    This means that any screen that display more than one button type has the potential to be slow. One way to dramatically decrease the number of requests is to aggregate all the images in one and use CSS background images. The latter is available since the first version of CSS, just specify the background-image attribute to display the image behind an element . This usage is called CSS Sprites. The code now looks like:

    <button class="update">Label</button>
    button.update {
      background-image: url('path/to/my/image');
      background-repeat: no-repeat;

    The astute reader will have remarked that the previous code has the same effect as the <img> in the <button>. The real usage is to use only the portion of the master image that we want, somehting akin to that:

    button.update {
      background: transparent url('path/to/my/aggregate') -50px -50px no-repeat;

    To aggregate the master image requires the right image tool. To compute the portion we want for each button is a pain in the butt (to speak politely).

    SmartSprites Logo

    Luckily, my old friend Jawr has the right feature to help me. Since version 3.2, it includes SmartSprites, a product that just does all aggregating and computing for me. How does that work? Just by putting some comments in your CSS:

    • to declare how the master(s) image(s) will be constructed
    • to tell which sprite will take part in which master image
    /** sprite: master-sprite-gif; sprite-image: url('../img/master-sprite.gif'); sprite-layout: vertical */ {
      background-image: url('../img/certificate_preferences.gif'); /** sprite-ref: master-sprite-gif; */
    button.two {
      background-image: url('../img/inbox_into.gif'); /** sprite-ref: master-sprite-gif; */
    button.three {
      background-image: url('../img/mail_forward.gif'); /** sprite-ref: master-sprite-gif; */

    The previous CSS is an example by which all three GIFs will be found at runtime under ../img/master-sprite.gif. If you look at the generated CSS, it will have the following look:{background-image:url('../cb3648025844/img/master-sprite.gif');background-position:left -0px;}
    button.two{background-image:url('../cb3648025844/img/master-sprite.gif');background-position:left -48px;}
    button.three{background-image:url('../cb3648025844/img/master-sprite.gif');background-position:left -96px;}

    Of course, the real generated CSS will have been concatenated and minified (see below).

    Note: I’m not a GIF expert but I suspect original GIFs should have similar color tables, otherwise, the aggregated GIF will look really strange.

    However, Jawr also provides some very interesting features, both old and new:

    • minification, for both CSS and JavaScript. You can also choose the minifying engine (embedded, JSMin or YUI Compressor). The latter is even able to obfuscate your source, thus even making your JS even lighter in the process
    • license inclusion, so that even minified sources can display their license
    • runtime GZip compression if the client browser supports it
    • HTTP header management so that requests for the same resources (beside the first) will be answered by a HTTP 304 - Not Modified code, thus avoiding unnecessary network traffic
    • i18n management in order to use Java standard properties files for internationalized messages in your JavaScript
    • JavaScript to use Jawr without taglibs in plain HTML pages (though it is not recommended since it adds a script to the page, thus another HTTP request)
    • possibility of extension, with new pre- and post- processors
    • ability to switch between development mode (no modification for resources) and production (virtual resources served by Jawr)
    • bundle preprocessing, so that the processing is not done at startup but instead at build time: this can be done either by calling an Ant task or by configuring a Maven plugin
    • for truly engaged application server administrators, support for JMX

    During the last year, it seems Jawr has gained some nice upgrades. I don’t know how many people truly use it but I think it deserves some interest when you need to optimize performance on the page loading time front.

    You can download the sources for this article in Eclipse/Maven format here.

    Categories: JavaEE Tags: jawr
  • Decrease your pages load time

    1. Generalities

    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).

    — Responsiveness article on Wikipedia

    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:

    1. Make JS and CSS external,
    2. Make fewer HTTP requests,
    3. Minify JS (and CSS).

    First point is pretty self-explanatory. Instead of putting JS code and CSS information in your HTML, you put both in external files and reference these from your page: no big deal, everybody does it nowadays. The second point is contrary to the first: for each file you have, you must make a separate HTTP request. So, the best solution is your main HTML plus a single JavaScript file and a single CSS file. The 3rd point is to minify those files, that is to remove comments, extra spaces and linebreaks, so as to make those files lighter. Options also include renaming the variables to make their names shorter (which can obsfuscate, deliberately or not).

    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:

    <!-- Executes YUI compressor on simple JS file -->
    <target name="simplest">
      <java jar="tools/yuicompressor-2.4.2.jar" fork="true">
        <arg value="-v" />
        <arg value="web/script/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:

    <!-- Executes YUI compressor on simple JS file -->
    <target name="simple">
      <java jar="tools/yuicompressor-2.4.2.jar" fork="true">
        <arg value="-v" />
        <arg value="web/script/simple.js" />
        <arg value="-o" />
        <arg value="${build.dir}/web/script/simple.js" />

    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 :

    import javax.servlet.Filter;
    import javax.servlet.FilterChain;
    import javax.servlet.FilterConfig;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    import javax.servlet.http.HttpServletRequest;
     * Filter that minifies JavaScript files. Can be used with CSS files with less configuration.
     * @author Nicolas Fränkel
     * @since 17 mars 2009
    public class YuiCompressorFilter implements Filter {
        /** Configuration object. */
        private FilterConfig config;
        /** Number of kept linebreaks. */
        private int linebreak;
        /** Munge. */
        private boolean munge;
        /** Verbose. */
        private boolean verbose;
        /** Should all semicolons be kept. */
        private boolean preserveAllSemiColons;
        /** Should optimization be disabled. */
        private boolean disableOptimizations;
         * This implementation does nothing.
         * @see javax.servlet.Filter#destroy()
        public void destroy() {}
         * Compress JS and CSS output.
         * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest,
         *      javax.servlet.ServletResponse, javax.servlet.FilterChain)
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
          throws IOException, ServletException {
            StringWriter stringWriter = new StringWriter();
            final PrintWriter printWriter = new PrintWriter(stringWriter);
            HttpServletRequest httpRequest = (HttpServletRequest) request;
            String path = httpRequest.getServletPath();
            InputStream stream = config.getServletContext().getResourceAsStream(path);
            Reader source = new InputStreamReader(stream);
            JavaScriptCompressor compressor = new JavaScriptCompressor(source, new BasicErrorReporter());
            compressor.compress(printWriter, linebreak, munge, verbose, preserveAllSemiColons, disableOptimizations);
         * Reads filter parameters.
         * @see javax.servlet.Filter#init(javax.servlet.FilterConfig)
        public void init(FilterConfig config) throws ServletException {
            this.config = config;
            String linebreakString = config.getInitParameter("linebreak");
            String mungeString = config.getInitParameter("munge");
            String verboseString = config.getInitParameter("verbose");
            String preserveAllSemiColonsString = config.getInitParameter("preserveAllSemiColons");
            String disableOptimizationsString = config.getInitParameter("disableOptimizations");
            munge = Boolean.parseBoolean(mungeString);
            verbose = Boolean.parseBoolean(verboseString);
            preserveAllSemiColons = Boolean.parseBoolean(preserveAllSemiColonsString);
            disableOptimizations = Boolean.parseBoolean(disableOptimizationsString);
            try {
                if (linebreakString != null) {
                linebreak = Integer.parseInt(linebreakString);
            } catch (NumberFormatException e) {
                throw new ServletException(e);

    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.

    5. Jawr

    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:

    • Bundling of any JavaScript or CSS file whatever the chosen directory structure,
    • Modifying those files dynamically, e.g. with ResourceBundle messages,
    • JavaScript and CSS minification (oh, what a surprise!) that can be done with either YUI Compressor or JSMin,
    • 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:

    • a servlet to serve JavaScript and CSS content,
    • 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:


    An example properties file will look like this

    #Turning on compression when possible
    #Using YUI compressor
    #Bundling into all.js
    #Bundled scripts
    jawr.js.bundle.all.mappings=/script/simple.js, /script/sub/b.js, /script/sub/subsub/a.js

    Then, you will use it like this in your page:

    <%@ taglib prefix="jawr" uri=""%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "">
            <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
            <title>Jawr test welcome page</title>
        <body onload="a();b()" />
    <jawr:script src="/script/all.js" />

    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:

    • bundling JavaScript files,
    • minifying them,
    • compressing the bundled file (if you browser supports it).

    As an example, it will only output two JavaScript alert boxes, but it will you the framework to build upon if you need to go further.

    6. Conclusion

    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.

    Categories: JavaEE Tags: jawrjsptaglibwebyslow