JSF: Suggestion for Performance Improvement

May 1, 2009

One of the areas of JSF that I think suffers compared to other models such as JSP, PHP, etc is that it requires two paths instead of one. In JSP, for example, code is compiled directly into Java bytecode. That code is then directly executed when the servlet is accessed. As a result, a single path is executed to render the content to the output stream. In JSF on the other hand, first a component tree is created and renderers associated with it. Once that tree is constructed and JSF enters the render phase, the tree is walked completely and content is written to the output stream. Thus, JSF requires two paths: one to create the tree and one to render it. As a result, JSF has overhead associated with it. On the plus side, that overhead buys the developer a much improved programming model and better MVC implementation. The component tree is a stateful tree that allows state to be associated to components (ie: a value for an input component). This allows JSF to have a very clean model for performing validation, actions, and rendering. However, I believe that the tree mechanism can be improved from a performance standpoint.

In JSF, when the FacesServlet is accessed, it asks its associated view handler implementation to restore or build a view or component tree. In Facelets, this tree is built by using Facelet TagHandlers that create a component for each tag instance adding the component to the tree. In JSP, the tags are associated to JSP tag handler classes that perform similar logic. In either scenario, the end result is a tree of components. When they create components, they use the JSF application to create the component by asking the application for a component with a given component type. As components are stateful, a new instance must be created per request. Thus, for a very large page with several components, it requires invoking several tag handler classes that end up retrieving the application to get the component which then creates the component by using reflection on the associated class type. This has two impacts to performance. First, you have to create several components for a given page and each of those invocations require memory allocation, initialization, referencing, setting attributes, etc…very expensive tasks. This also impacts garbage collection by creating excess garbage per request. Second, it has to use reflection to create the classes and reflection is generally slower than directly invoking the new operator. So, what can we do to help?

In principle, components in JSF are really not 100% stateful. From a ease of development standpoint, they prolly are, but from a performance standpoint, they really are not. What I mean by that statement is that a page does not change from one request to another meaning that components do not necessarily need to have separate state between requests. The content behind the component changes (ie: via EL expressions and backing beans), but the components themselves are exactly the same from request to request. For example, a panel group component is nothing more than a grouping component that is used to group multiple components (typically in a ‘div’ or ‘span’ in HTML). The component has several attributes such as styles, style classes, dimensions, titles, etc. On a page, it may be defined such as:

<h:panelGroup id="test" styleClass="#{MyBean.state == 'valid' ? 'valid class' : 'invalid class'}">...</h:panelGroup>

When that gets created by the tag handlers, it results in a panel group component that includes a static string value for the id property and an EL expression for the styleClass property. When user X hits the page such that MyBean.state evaluates to ‘valid’, the EL expression is evaluated and evaluated in the context of the user. When user Y hits the page, the expression is evaluated in that user context which could cause the expression to be evaluated differently. In neither request did anything in the component change.

I am making this point on components not being stateful for two reasons. First, by being stateless, they can be re-used across requests (similar to renderers). Second, by being stateless, they do not need to save their state. State saving is another huge bottleneck in JSF and reducing the number of components that take part in saving state can improve performance vastly. There is already a lot of work being done in this area in JSF, so I will not touch on it further. The first issue is of my primary concern. If we can truly call a component stateless and re-use across requests, then we can reduce the number of reflection calls and number of instantiation calls. This can dramatically improve throughput for pages with several components on a page. But how do you know if a component is stateful or not and better yet, how would you even fix this in JSF when it is already built on the principle of stateful components?

To answer the first question, the easiest way is to check out what instance variables a class uses. If a class uses only value bindings or EL expressions, it can be stateful since expressions are evaluated per request by using the current FacesContext of the active thread (via ThreadLocal). Further, if the attributes in the component are tied directly to a tag handler attribute (ie: styleClass, style, etc), then they are generally set once by the page and never change…ie: they are stateless to subsequent requests. Generally, if a component has non-attribute specific variables such as state, values, etc, then they are stateful. For example, the input components (ie: UIInput) have a local value instance field for managing the state through the lifecycle (from validation to conversion to rendering). Because that value can change request to request, input components are generally stateful. However, the number of input components on a page to non-input components (ie: visual components) is drastically smaller. As a result, we can make several components stateless. But how?

My solution to this problem are annotations. I am an avid supporter of annotations as it is a great method for metadata within class files without having to maintain a separate configuration file (not to mention custom parsers, etc). Similar to EJB’s model of @Stateful and @Stateless, I would recommend a @Stateful and @Stateless annotation for component classes. So, you could mark a panel group as stateless via:

@Stateless
public class UIPanel extends UIComponentBase
{
   // normal code
}

For an input component, you might mark all input components as stateful via:

@Stateful
public class UIInput extends UIOutput
{
    // normal code
}

You can then use this annotation in the JSF application class when components are created. Tag handlers invoke the method createComponent(String componentType) to create the component. Thus, in that method you can lookup the class for the component type. From that class, you can look for the @Stateful or @Stateless annotation. If @Stateful is found, then you would use reflection to create the instance. Otherwise, if @Stateless is found, you would look for the already created instance and return that. When most of the components on the page are stateless, you will end up reducing the instantiation of new objects per request and reduce the amount of state saving and garbage, all resulting in performance improvements, especially when related to overall throughput and concurrent connections.

However, this solution does have its caveats and issues. For example, currently tag handlers after having created the component from the application, they then proceed to setting the EL expressions or literal values on the components based on the tag attributes. For newly created stateful components, this step is needed. However, for already created stateless components, this step is not needed and should not be used to improve that performance. Thus, those tag handlers (JSP or Facelets) would need to be updated. Further, there is the issue of what is the default state of stateless components are how do they get initially created. We discussed how we can re-use them in the application, but you must first create and set the attributes. Thus, the tag handlers may again need some mechanism to check if the component has been either initialized (either via @Stateful or via first access to @Stateless) or not.

The second issue that would need work and testing is synchronization of components. If the components are going to be re-used across requests, that means they will be invoked by multiple threads simultaneously. As a result, synchronization becomes a concern. Further, as synchronization can quickly become a bottleneck as well, this needs thorough investigation to properly implement stateless components.

The third issue is that dynamic components that impact the tree or component state will not work. One example of this is JSTL. In JSTL, the tree is changed based on the evaluation of expressions when the page is being built per request. If those invocations can impact a component such that its children, state, etc change request to request, then they must be stateful to properly work. However, the whole issue of children, anyways, needs to be handled to support mixing a stateless parent with stateful children (ie: a stateless panel group with stateful input components). If the stateless component is re-used, then that implies that it has the same children per request. As the stateful components are changed request to request, that would not be the case. Thus, there would need to be some mechanism such that the stateless components knew how to access their stateful children. Dynamic components such as custom component bindings or controllers that modify components on the fly by changing children, attributes, etc would also fail as they would impact a stateless component for every request rather than a single request.

All in all, I truly believe that there can be some mechanism in place to re-use components to avoid the penalty of creating the component tree and the penalty of state saving. However, I do not have all the solutions either, particular for the above caveats. This message is meant to get people thinking on ways we can solve the issues to further improve JSF so that not only is it an easy to use MVC model but also a fast, reliable, and performance-centric solution.

4 Responses to “JSF: Suggestion for Performance Improvement”

  1. Thanks…

    Good site! I found your site on yahoo and have saved it in favourites for future reads. Cheers keep it up…..

  2. Insightful suggestion..

  3. Looks a lot like this article I saw by Hiren Dutta :

    http://hirenscafe.blogspot.com/2010/03/jsf-application-tuning-webapp.html

  4. Re Youssof’s comment, I came across both posts too but I checked the dates on this post (2009/05) and Hiren’s (2010/03). This is a well structured and comprehensive post which has, regrettbly, been plagiarised.

    Thanks Nicholas