JSF Central - Speed up your Data-Driven JSF/Seam Application by Two Orders of Magnitude – Part 2
JSF Central

 
 Home 
 
 Products 
 
 Articles & Books 
 
 Resources 
Speed up your Data-Driven JSF/Seam Application by Two Orders of Magnitude – Part 2
 
Speed up your Data-Driven JSF/Seam Application by Two Orders of Magnitude – Part 2
(continued)
by Dan Allen
27 Mar 2009 01:30 EDT

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.


Taming component IDs

JSF populates the id attribute on the rendered HTML for most components, which Ajax4jsf relies on heavily to do partial page updates. These IDs are like lawyers: if you don't define one, one will be provided for you. There are pitfalls in both scenarios. Let's first assume that you are diligent and provide your own ids. Being a thorough developer, you are very expressive to make it easy for other developers to read your code.

<h:form id="dataTableContainer" ...> ... <h:dataTable id="dataTable" ...> ... <h:column> ... </h:column> ... </h:dataTable> </h:form>

As you can see, the IDs chosen are quite long, which directly affects the size of the response. Thoroughness here gets punished. What's worse is that the content length is compounded because JSF aggregates ids of most hierarchically related components. In particular, if a component is a NamingContainer, which both <h:form> and <h:dataTable> are, then the ID of the component is inherited by its children. Here's the generated ID on one of the cells in the table:

dataTableContainer:dataTable:0:j_id110

As you can see, the IDs we provided are joined using a colon and the id of the table column is provided for us. Considering we have 8 columns and 100 rows, the pattern of this ID is repeated many times. Thus, we want to make these IDs as short as possible. Even the generated IDs are too long. Ideally, we want to see an ID like this:

dc:dt:0:tx

This id would be achieved using the following JSF template fragment:

<h:form id="dc" ...> ... <h:dataTable id="dt" ...> ... <h:column id="tx"> ... </h:column> ... </h:dataTable> </h:formv>

Putting all other optimizations aside, this is the one you should focus on first. Since the IDs are nested, it should make it easy to create short IDs that are unique. That brings us to our fourth lesson.

Lesson #4:Explicitly assign IDs to all JSF components and make them as short as possible.

Let's think about what else is repeated over and over: resource paths and view IDs.

Terse path names

Again, you may be inclined to make expressive names for resources such as images, but you pay a price for doing so. Keep the names of the resource files and the name of the directory that contains them as short as possible. Here's an ideal path for the edit image in each row:

/i/e.png

If you don't want to be overly cryptic, you can settle for a slightly longer name and take the minor performance hit. If it bothers you to use terse and cryptic names to optimize performance, then I suggest that you put work into a build system that is capable of compressing the resource paths and shifting files around to isolate the optimization process from development.

Let's talk about the file name of a JSF page, otherwise known as the view ID. In classic JSF command components, the length of a view ID does not present a problem because the view ID is written into the response once per form. However, in the Web 2.0 world, Ajax is sending the request and you typically have to tell the Ajax call where the request is going (truthfully, I don't know why RichFaces can't just assume it's sending the request to the current URL, which is the standard procedure for a JSF postback). Now that we have these Ajax-enabled command components in every row, we need to reduce the size of our view ID. Here is a suitably terse name for the Benthic Measurements list page:

/benthics.xhtml

In the source of the page, you'll notice that the action URL that corresponds to this view ID appears in the Ajax submit function call that is invoked when the target is clicked:

onclick="A4J.AJAX.Submit('_viewRoot','dc',event,{'parameters' :{'ajaxSingle':'dc:dt:1:e','dc:dt:1:ec':'dc:dt:1:ec'} ,'actionUrl':'/edas2-perflab/benthics.seam'} )"

You can get as cryptic or verbose as you want with file paths. Just keep in mind that you are making a trade off between readability and performance. But even before you start trimming your resource file names and view IDs, think about one tax that you pay on any local URI: the name of the context path where your application is running. Ideally, you would run the application on the root context path, relying on virtual host name if you need to have several applications running on the same application server. If that's not possible, try to use just one or two letters for the context path. The end user really doesn't need to know what you call the application internally. Currently, our application uses the context path /edas2-perflab, which is overly verbose. In JBoss AS, you can switch the application to the root context path by adding the following element to your application's /WEB-INF/jboss-web.xml descriptor:

<context-root>/</context-root>

Now the action URL for /edas2-perflab/benthics.seam shortens to /benthics.seam.

That takes care of path names. Now let's consider other markup that the components generate.

Resources



RSS feed(all feeds)

The Editor's Desk
Podcasts
Inside Facelets
In the Trenches

Site version 1.83  Report web site problems

Copyright (C) 2003-2015 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.