How to improve JSF/RichFaces performance
How to improve JSF/RichFaces performance
We have a complex ERP application that has RichFaces 3.3, JSF 1.2, Hibernate, Spring, MySQL which is running under JBoss on a 16GB AWS CentOS instance. This application has lot of grids, calendars, popups, tabs and richfaces components that any ERP application is expected to have.
Over a period of time, we realized that the performance of our application is pathetically slow and we started exploring options to improve the performance. We read several articles on this and to our surprise we discovered that lot of people are annoyed with slow performance of RF3.3. After various readings, we did following tweaks:
- Tweaked the MySQL for better performance throughput.
- Put together EHCache which has seamless integration with the Hibernate.
- Tweaked the web.xml with all the suggestions available on the net.
- Configured Niko parser (and our UI was all messed up!!)
- Removed the theme changer, changed the loading strategy etc.
- Used A4JRegion, Ajaxied tab loading etc
- Used the ‘minimalist’ RichFaces themes
- Changed bean scope
Our performance did improve but it was a very slight improvement. Our application was STILL crawling. And the most baffling performance bottleneck was that the simple page load itself was taking anywhere between 10-20seconds.
Then we started doing the YourKit profiling and we could NOT spot any ‘bottleneck’ from those profiling results. Now we started putting simple log statements at the bean level to see how long it is taking for an average call to process and we discovered that the time taken by these calls was really a very small fraction of the total time taken to load the page.
At this point of time we were planning to move to other versions/frameworks but looking at the amount of changes we had to do (all those JSP files would have to be converted to xmlns to begin with if we would have decided to migrate to newer versions of JSF/RF), we decided to spend some more time in exploring the ways to improve the performance.
Finally after debugging bit more we did following things to fix it (yes we mean it!!) and now every single page of the application loads in less than 3 seconds. This includes the really big pages with a lot of data on it. 🙂
If you are facing the same problem, please follow the steps below and you should be able to fix these performance bottlenecks:
- JBoss gzip compression is NOT enabled by default. This means that all the data that is being received from the server is taking long time to reach the client. As with all the calls, the whole page’s, XML comes back to the client, this means that we are taking long time to actually receive the response. First enable the compression so that your responses/loads/re-renderings etc become faster. As per this http://stackoverflow.com/questions/2994420/enabling-gzip-compression-for-jboss stackoverflow entry, this is how you enable it:
-
edit JBOSS_DIRECTORY\server\default\deploy\jbossweb.sar\server.xml
Change this line to:
<Connector protocol="HTTP/1.1" port="8080" address="${jboss.bind.address}" connectionTimeout="20000" redirectPort="8443" />
<Connector protocol="HTTP/1.1" port="8080" address="${jboss.bind.address}" compression="on" compressableMimeType="text/html,text/xml,text/css,text/javascript, application/x-javascript,application/javascript" connectionTimeout="20000" redirectPort="8443" />
In compressableMimeType make sure you add xml/html/javascript and css. If you are using really big JPEG images, do add jpeg to this list. Do NOT add the compression for small png icons as compression and decompression, can actually end up taking more time then the actual performance benefits of the compression.
Restart your Jboss server and you should already see some decent performance benefits :). Now lets move to the second big performance booster:
- In JSF/RF, for the JS files there are various load strategies available. First you should set the load strategy to ALL. In your firebug, you would see 3-5 JS files being loaded (depending upon the theme that you are using). Open these JS files in the browser in exact same order as they are being loaded. Copy content of each of these files in to 1 JS file named common.js. Use any JS Compression utility to compress this common.js file (we used Yahoo’s compressor). As all these JS files are static, you can actually cache it. JBoss by default gives a simple way to serve static content. Move this compressed file in the ROOT.WAR folder of Jboss and include this compressed common.js file (the one that is in the ROOT.WAR) in your application. Change the load strategy to NONE as we would be receiving the required JS files from that minified JS files and NOT from the JSF. Now, deploy your application again and restart the JBOSS. Now you should be seeing really huge performance improvements.
Also note that this last step is not required in the latest versions of JSF/RichFaces as they give an option to specify the base URL from where the static content is delivered. You can directly point it to the place where your static content is delivered from.
Let us know if this article helped you. Also let us know if we can be of any help in improving the performance of your RF/JSF application. Good Luck!!