Tuning Web Applications on JBoss AS Part 2

Increasing the performance of JSF and RichFaces

Until now, we have covered two common components, which are part of almost any web application. Unfortunately there is no magic switch which can improve dramatically the performance of single JSF UI components. However, some general best practices do exist to accelerate the whole JSF lifecycle. We can group them roughly into three areas:

• Configuring JSF state saving efficiently

• Using Ajax support to reduce the cost of page rendering and data transmission

• Loading external files (JavaScript/CSS) efficiently

Configuring JSF state saving efficiently

One of the most important settings, affecting the performance and the memory used by JSF UI components, is where to save the session state. You can opt between saving the state in the server (the default), which provides better performance, or saving it in the client which reduces the memory footprint, at the cost of a loss of performance.

Besides this, by using server-session state, you can have control over the serialization process, which is mandated by the JSF specification, to keep the application state consistent through the JSF lifecycle. Thus, the suggested guideline is to leave to the default (server) session-state saving:

tmp181-88_thumb


 

 

tmp181-89_thumb

We have benchmarked the dataTable example (from the previous section) using the two different session-state saving methods. As a result, the server-state saving method produced a 15 percent higher throughput:

tmp181-90

If you find excessive memory usage, you can limit the amount of Views to be stored in the session:

tmp181-91_thumb

An additional performance hit can be achieved by setting the compression and serialization of the state in the session to false:

tmp181-92_thumb

The above optimizations cannot be used when saving the state to the client:

tmp181-93_thumb

You can, however, specify a different serialization factory for your application, like org.apache.myfacesJbossSerialFactory, which delivers better performance:

tmp181-94_thumb

Benchmarking our application using JbossSerialFactory showed a better performance for our application using client state saving. The performance, however, is still inferior to the server state saving method:

tmp181-95

In order to install JbossSerialFactory on your application, please refer to the following link, which documents all the necessary steps: http://wiki.apache.org/myfaces/Performance.

Using Ajax to speed up your JSF applications

One of the major upgrades of JSF 2 release is the addition of Ajax support for UI components. By using Ajax development techniques, web applications can retrieve data from the server asynchronously in the background without interfering with the display and behavior of the existing page. This leads to an increase in interactivity with the website and a boost in performance, since only a portion of the web page can now be updated as a consequence of users’ actions.

One of the main advantages in using JBoss’s RichFaces component library is Ajax-native support for its UI’s components. For example, if you need to limit the part of the web page which needs to be updated, you can do it by means of the reRender attribute.

In the following code snippet, we are requesting a partial rendering of the web page by means of the update command button, which will re-draw just the info panelGrid:

tmp181-96_thumb

A closely related feature is the ajaxSingle attribute, which allows sending only a reduced set of attributes for processing, instead of the whole form attributes:

tmp181-97_thumb

Another area where you could expect some performance hits are Ajax filters. In an Ajax request, a filter is required for correct functioning of the partial page refreshes. You can define a filter in your application’s web.xml with the following XML fragment:

tmp181-98_thumb

What this filter does is to tidy all HTML responses so that they are valid XHTML (thus XML compliant). This is needed as dynamic DOM updates in the browser need correct XML.

Parsing HTML is, however, a CPU and time-consuming operation. So, you should use the most efficient parser available. RichFaces has a few parsers built in. The default one is based on a Tidy parser but it is quite slow. The Neko parser is considerably faster and can be used by setting the following context params:

tmp181-99_thumb

The following image shows a benchmark, which compares an Ajax-driven form submission using the default Tidy parser and the Neko parser:

tmp181-100

Be aware that the Neko parser requires that the application’s markup code is strictly verified. Code that is not strictly verified can cause a number of errors and corrupt layouts when used with the Neko filter.

A last configuration tweak for the RichFaces Filter can be applied by setting its forceparser parameter to false. With this setting, just Ajax requests will be tidied, thus speeding all other requests.

tmp181-101_thumb

Speeding up CSS and JavaScript file loading

As you can see from a quick inspection of a rich web page, lots of CSS and JavaScript files are used to produce the intriguing GUI. JavaScript, unfortunately, has a dark side to it that not many people are aware of. It causes the browser to stop everything that it’s doing until the script has been downloaded, parsed and executed.

Some browsers, for example Google’s Chrome or even IE8, can load files in parallel so that two smaller JavaScript files might load more quickly than one massive file. In most cases, however, you should configure your application to load the external file with a single external call. This can be done by means of the RichFaces’s LoadStyleStrategy parameter:

tmp181-102_thumb

Be aware that when using the all load strategy, you need to turn off script compression to get it working.

tmp181-103_thumb

 

 

 

tmp181-104_thumb

 

Tuning web services

The other broad category of web applications includes web services, which is a typical B2B technology. Web services have deeply changed the landscape of B2B services by introducing a common transport protocol for network communication, which before was left to different kinds of adapters and plugins provided by the single application server.

How do web services actually bridge different systems? Web services use XML as the standard for exchanging data across disparate systems. Specifically, the XML content needs to be converted to a format that is readable by the Java application and vice versa. Data binding is the process that describes the conversion of data between its XML and Java representations.

The current standard for designing web services is JAX-WS, which uses Java Architecture for XML Binding (JAXB) to manage all of the data binding tasks. Specifically, JAXB binds Java method signatures and WSDL messages and operations, and allows you to customize the mapping while automatically handling the runtime conversion. This makes it easy for you to incorporate XML data and processing functions in applications based on Java technology without having to know much about XML.

The following image shows the JAXB data-binding process:

tmp181-105_thumb

The core process, which allows the translation of XML into Java Objects and vice versa, is known as marshalling and unmarshalling. As with all libraries dealing with XML, they are CPU-intensive operations, which can easily become a performance bottleneck. Thus, most of your tuning efforts should be directed at reducing the graph of Java Objects to be converted into XML.

Difference between serialization and marshalling

Marshalling and serialization are loosely synonymous in the context of remote procedure call, but semantically different as a matter of intent.

Serialization is a general technique for converting objects to sequences of bits that can be transported to a different VM. Serialization is used by EJB to transport objects from the client JVM to the server JVM.

Marshalling, on the other hand, means bundling up parameters for a remote method call. Under SOAP, marshalling uses a much more complex approach, translating parameters to XML.

Next post:

Previous post: