Thursday, February 9, 2012

Optimizing Resource Loading with RichFaces 4.2

HTTP connection is an expensive commodity. But if you will look on a traditional rich JSF application, there are many resources for components which need to be loaded, thus many connections need to be established.

The high number of HTTP requests significantly affects application load time and thus overall performance. This applies especially for high-latency network connections like geographically distant places and for mobile networks.

Here you can see profile of loading RichFaces page. You can view sequence of requests made by browser to load all the page dependencies.

JavaScript dependencies

CSS dependencies

When you will look into page source, you will see these resource dependencies defined in the head of the page:

<head> section will all the dependency links


Simple optimization of resource loading comes in form of aggregating several requests into one, thus lightening the load on both the server and the network.

The RichFaces Way

RichFaces offers you the simplest solution available - all RichFaces resources packaged in one file for each resource type - one JavaScript package (packed.js), one CSS package (packed.css).

The only thing you need to do is turn the packaging feature on.

Enabling resource optimization

Open the web.xml file in your project and add following lines:

<context-param>
    <param-name>org.richfaces.resourceOptimization.enabled</param-name>
    <param-value>true</param-value>
</context-param>
Notes: Resource optimization was introduced in RichFaces 3.x as resource loading strategies.

It was reintroduced in 4.1, but for 4.2, its configuration was slightly changed to be more clear and concise. This blog reflects changes committed with RichFaces 4.2.0.CR1. Read more about changes in release blog.

Now, deploy and open your application. When you will open page source, you can see that number of page resources (<script> and <link> elements in the head) was significantly decreased:

<head> section with links to optimized resource dependencies


Also the page load profiles looks much better:

Optimized JavaScript resources

Optimized CSS resources


Packaging and Compression

Resource optimization itself is composed from two features: packaging and compression.

Packaging phase aggregates several resources into one, while compression do JavaScript/CSS compression and obfuscation (powered by YUI compressor).

By default, both packaging and compression are applied on RichFaces resources (in production stage).

However resource optimization is also controlled by the stage of the project. Why?

Development mode

Packaging is not convenient in development project stage.

When you are developing application, some problems may occur in form of JavaScript errors or wrong look because of styling issues. In these cases it’s handy to debug these JavaScript or CSS resources in uncompressed state.

The state of the project is controlled with web.xml switch:

<context-param>
    <param-name>javax.faces.PROJECT_STAGE</param-name>
    <param-value>Development</param-value>
</context-param>

It will force load uncompressed, but packaged resources - great for debugging the app!

Troubleshooting

When you will have any issues, be sure to look into

Troubleshooting - Resource Optimization article


Summary

As you can see, with RichFaces Resource Optimization, you can achieve decrease of number of resource requests. These resources are also cached by the browsers, so after first page, client get perfect responsiveness.

On the other hand, you are increasing the size of resources which are necessary to be loaded on first request, since all of the RichFaces component resources are bundled in one file.

You need to choose between fast start of the app and responsiveness of the app after first request.

What's the best option for your application, it’s up to you! ;-)

Future Improvements?

We have several ideas how to improve resource loading if it is really critical for your application:

  • several smaller files packaged for certain occasions (core, tables, panels, etc.)
  • provide you maven plugin which will create custom packages just to fit your application needs during the application build!


If you would like to implement any of these features, or have any other ideas for enhancements, be sure to let us know!

10 comments:

  1. Very nice! Are you thinking of adding compression or minification to the CSS and JavaScript?

    ReplyDelete
  2. Hey Wes, CSS and JavaScript resources are already compressed using YUI compressor. We can additionally GZIP them, there is feature request for that - https://issues.jboss.org/browse/RF-11438 .

    ReplyDelete
  3. Is "maven plugin which will create custom packages just to fit your application needs during the application build" ready?

    ReplyDelete
  4. Hey Bernard, such plugin is http://docs.jboss.org/richfaces/latest_4_X/maven-richfaces-resources-plugin/, but it scans just component resources - it does not specifically scan resources defined in XHTML and you cannot add any other resources manually.

    ReplyDelete
  5. "introduced in RichFaces 3.x ... reintroduced in 4.1" - does this mean that there's no such thing at all in 4.0? Is there a way to optimize resources in 4.0? (switching to a different version is out of the question)

    Thanks!

    ReplyDelete
  6. You are right, Piotr, RichFaces 4.0 didn't have this feature. You should be able to reimplement it as set of RichFaces 4.0 extensions, but it would be probably less work to upgrade.

    ReplyDelete
  7. Hello Lukas, This looks like it couldn't be more straightforward, but I cannot for the life of me get this working in my system - currently using RF 4.3.3 and JSF 2.1.7 - Is there any chance you could post the links from the xhtml page, i.e the before shots, so I can compare against the ones I am using?

    ReplyDelete
  8. Hi
    I have added context param for compressing script in my web.xml

    org.richfaces.resourceOptimization.enabled
    true


    but after adding i am getting an javascipt error and none of the action button is working on webpage
    Java script error is jQuery.atmosphere is null or not an object so please suggest why after adding this context param we are getting error.

    Also we have an another problem that the a4j:request get stuck and user has to refersh the broswer every time and after that it works fine.

    We are using JSF 2.0 and RICHFACES 4.2 Final

    ReplyDelete
  9. This comment has been removed by the author.

    ReplyDelete
  10. A tablet can be a great asset for anyone who loves to stay in touch with the web world. This blog is very useful in optimizing android tablets,thank you for sharing. If you want to know about Application Packaging, then have touch on that.

    ReplyDelete