In the second installment of this two-part article, Dan Allen continues his discussion of some common performance problems you may encounter when using JSF components, Seam components, and the EL. You'll learn about the set of best practices for eliminating them that led to an improvement of two orders of magnitude in the performance of his application.

In the first part of this article, I began briefing you on optimizations I made to maximize the responsiveness of a JSF application that I developed out in the field. I cited performance problems caused by casually accessing components from a JSF view, then presented a set of best practices to eliminate this unnecessary overhead. Despite the progress made by the end of the first part, you had not yet witnessed the two orders of magnitude in performance improvement that was promised.

In this part, the additional gains will be achieved by leveraging partial page rendering-provided by the RichFaces JSF component library and by slimming the response. Partial page rendering cuts out the overhead of rerendering the entire page after each user interaction, which turns out to be the real bottleneck in most traditional web applications, and instead redraws only the areas of the page that have changed. Naturally, you want the replacement HTML source to be as condensed as possible. These optimizations allow the responsiveness of a web application to measure up to its desktop counterpart.

Tapping into Ajax

When the user performs an operation on the screen, such as selecting a row for editing or paginating a result set, we only want to rerender the area of the page that is affected. Using the data-driven application presented in the first part, that means redrawing the data table and its pagination controls. (Note that it's possible with Ajax4jsf to rerender a single row, when applicable, but I have found it to be more trouble than it's worth).

Putting numbers aside, using Ajax is going to make the application feel far more responsive because the browser does not have to bootstrap a whole new page and all the assets that come along with it. Research has shown that creating HTTP connections is more costly than rendering large pages. Partial page rendering accounts for these findings by treating the static areas of the page and its associated assets as completed work, and focusing solely on retrieving updates. This section will support my recommendation that you should always consider using Ajax in your application, as it truly does eliminate a lot of overhead.

Accessible Ajax with Ajax4jsf

Turning regular JSF postbacks into Ajax requests is pretty simple with Ajax4jsf. However, if used inappropriately, you won't get all the performance gains you are looking for. We'll get to that in a second. First, begin by changing your <h:commandLink> and <h:commandButton> components to the ones from Ajax4jsf: <a:commandLink> and <a:commandButton>. Next, select what you want to rerender. You reference the areas of the page to update using a comma-separated list of the regions' component IDs in the reRender attribute of the command component. If you are paginating, you need to rerender the whole table and the pagination controls (dataTableContainer). If you are transitioning into edit mode, there's no need to requery or update the pagination, so you only have to rerender the table itself. Here's the code for the pagination controls:

The code for the edit control buttons in each row is similar. Here's how the edit button is defined:
<a:commandLink id="edit" action="#{benthicMsmntEditor.editItem}"
rendered="#{_item != conversationScope.get('itemInEditMode')}"
reRender="dataTable" ajaxSingle="true">
<h:graphicImage value="/img/edit.png" alt="Edit" title="Edit"/>
</a:commandLink>

What's important about using an Ajax request is to keep it simple. You don't want to perform a lot of processing on the server because then the users aren't going to get the "instant" feedback they are expecting. You can drastically reduce the portion of the component tree that is processed by JSF by using either the <;a:region> tag or the ajaxSingle attribute on an Ajax4jsf component. Let's focus on ajaxSingle.

Keeping the Ajax call brief

By default, JSF processes the whole component tree on a postback because it doesn't know where events may originate or which input fields within the submitted form contain new data. What the ajaxSingle attribute does is tell JSF to advance directly to the component that was activated, process events from that component, and re-encode it as if it were the only component on the page. The result is a drastic speed increase in the processing, independent of the size of the component tree. In fact, the only time you would forgo using ajaxSingle is when you need to capture input data from a form (a classic form submit).

When deciding whether or not to use this attribute, ask yourself if you are capturing form data or whether JSF is simply using the form submit to perform server-side work (a contrived form submit). In JSF, it's most often the latter.

Note: Interestingly enough, ajaxSingle is also a drop-in replacement for immediate, which is excellent since immediate is so poorly understood. When ajaxSingle is placed on a command component (such as a button), the form data is not processed, and hence no validation/conversion failures can occur, thus eliminating the need for immediate.

Having shifted all interactions to the Ajax bridge, it's now time to look at the performance gains. Of course, when using Ajax, the tax of rendering the portions of the page outside of the data table is gone. The performance on the server is also no longer a primary concern. Now what matters is the size of the response. Unfortunately, giving timing results here would be arbitrary because it's highly dependent on the speed of the network (and I'm testing against my own box). We have to focus on what we can control.

Trimming down the response

So what affects response size? The answer is, every character in the view. Every character that you type that is encoded into the response, as well as the markup that the JSF components generate, affects the size of the response. That includes:

Component IDs

View IDs

The path of images, external JavaScript files, and CSS

The application context path

Embedded JavaScript

Inline styles and names of style classes

Erroneous markup that is encoded into the response

As you can see, there's lots of room for improvement in this category. I want to focus on component IDs first, since they are the biggest culprit.

Dan Allen is a Senior Software Engineer at Red Hat and author of Seam
in Action. He has over eight years of development experience using
technologies that include Java frameworks (Seam, JSF, EJB3, Hibernate,
Spring, Struts), testing frameworks (JUnit, TestNG), JavaScript and
DOM scripting, CSS and page layouts, Maven 2, Ant, Groovy, and many
others.

After graduating from Cornell University with a degree in Materials
Science and Engineering in 2000, Dan became captivated by the world
of free and open source software, which gave him his debut in
software development. He soon discovered the combination of Linux and
the Java EE platform to be the ideal blend on which to build his
professional career, with his interests equally divided between the
two platforms.

Dan is a member of the Seam project, a dedicated open source
advocate, and a Java blogger. He lives with his extremely supportive
wife in Laurel, MD. You can keep up with Dan's development
experiences by subscribing to his blog at
Mojavelinux

Copyright (C) 2003-2014 Virtua, Inc. All Rights Reserved. Java, JavaServer Faces, and all
Java-based marks are trademarks or registered trademarks of Oracle Corporation. in the
United States and other countries. Virtua, Inc. is independent of Oracle Corporation. All other trademarks are the sole property of their respective owners.