Performance Optimization for Backbase JSF Applications

The ultimate goal of any software project is to have it function reliably and of course perform as expected. In this article, we will indentify some tips on how you can improve the performance and reliability of your Backbase JSF applications. This article is targeted at Backbase JSF releases from 4.2 upwards.

Overview

Over the past few years, we have seen projects struggling with their startup and rendering time. Building a high performance JSF application is not complicated however; you just need to adhere to certain design patterns in your application. Obviously, it is good practice to consider making an application that performs well from the very start, rather than deferring this to a later stage in the project lifecycle.

The topics that will be covered in this article include:

  1. The application tag concept
  2. Backbase islands
  3. Using the "rendered" attribute
  4. Static versus dynamic file inclusion
  5. Bind the component
  6. Use plain HTML or a client widget for templating
  7. Combine TDL definitions into one file
  8. Remove the unnecessary component tree
  9. Avoid using the UIBackbaseComponentBase.setStructuredDirty(true) explicitly

The <bjsf:application/> tag

The application component is responsible for loading the Client Runtime engine. In your JSF Framework web application, the Backbase JSF Server Runtime and the Client Runtime manage communication between the web server and the client browser. The Client Runtime is installed as a web application in your servlet container, and is downloaded transparently to the client on an initial request. After the application component is instantiated, the resources on which the page depends must be loaded.

Prior to Backbase JSF 4.2, all Backbase code had to be written within this tag, which resulted in all components (including non-Backbase tags) residing within the Backbase model space. Every component within this tag is rendered following the initialization explained above. As a result, non-Backbase components, such as a simple HTML <table/>, are rendered at the same time as Backbase components. By placing the table outside of the application tag, it will be rendered first, and the Backbase components nested in the table will be rendered afterwards.

Example

<body>
        <f:view>
                <bjsf:application>
                        <f:verbatim>
                                <xi:include href="/backbase/4_3_1/bindings/config.xhtml_btl.chameleon.xml" parse="xml" />
                                <xi:include href="/backbase/4_3_1/bindings/www.backbase.com.2007.jsf.client/server.xml" parse="xml" />
                                <bjsfc:server url="index.jsf" identify="id" loadingMessage="__loadingMsg" />
                                <b:loadingMessage id="__loadingMsg">Loading...</b:loadingMessage>
                        </f:verbatim>
                </bjsf:application>

                <table border="1">
                        <tr>
                                <td style="width: 145px; height: 30px">
                                        <bjsf:inputText style="width: 140px; height: 30px" value="Backbase Component1" />
                                </td>
                                <td style="width: 145px; height: 30px">
                                        <bjsf:inputText style="width: 140px; height: 30px" value="Backbase Component2" />
                                </td>
                        </tr>
                        <tr>
                                <td style="width: 145px; height: 30px">
                                        <bjsf:inputText style="width: 140px; height: 30px" value="Backbase Component3" />
                                </td>
                                <td style="width: 145px; height: 30px">
                                        <bjsf:inputText style="width: 140px; height: 30px" value="Backbase Component4" />
                                </td>
                        </tr>
                </table>
        </f:view>
</body>

As the table is not processed by the Backbase engine, there is no need to include this in the model space. For more information about the model space, refer to the Performance Tuning articles. Reducing the number of nodes within the model space will improve application performance. The way in which we separate the model-view concept (islands) is explained in the next section.

Backbase islands

The example in the previous section showed a simple table with nested Backbase components. Since the code is not within the <bjsf:application/> tag, it is not within the model space. However, in order for a Backbase component to be rendered, it must be within the model space. Fortunately, the Backbase JSF edition is intelligent enough to take care of this by automatically wrapping Backbase components with an <xmp/> tag, which marks the space parsed and rendered by the Client Runtime in the browser. These spaces are also known as Backbase islands. By creating islands we can separate non-Backbase tags from the model space, so that we can improve performance. As a result, the code generated to render a <bjsf:inputText/> within the <td/> would be as follows:

JSP code

<td style="width: 145px; height: 30px">
  <bjsf:inputText style="width: 140px; height: 30px" value="Backbase Component1" />
</td>

Code rendered in the view space

<td style="width: 145px; height: 30px">
        <xmp backbase="true"
                xmlns=http://www.w3.org/1999/xhtml
                xmlns:xi="http://www.w3.org/2001/XInclude"
                xmlns:b="http://www.backbase.com/2006/btl"
                xmlns:e="http://www.backbase.com/2006/xel"
                xmlns:c="http://www.backbase.com/2006/command"
                xmlns:bjsfc="http://www.backbase.com/2007/jsf/client"
                xmlns:bf="http://www.backbase.com/2007/forms">

                <input type="text" name="_idJsp2" id="_idJsp2" style="width: 140px; height: 30px" value="Backbase Component1" />
        </xmp>
</td>

Backbase islands in an application are rendered asynchronously. This means that a Backbase island with a process heavy component like listGrid will be rendered later than another Backbase island that contains an inputText component.

Based on the example above, it will create two backbase islands. Every bjsf component and client widget that is wrapped within an xmp tag with a backbase="true" attribute will be defined within the model space so that they will be rendered by the Backbase Client Runtime. Likewise, the non-Backbase components or widgets will not be processed by the Backbase engine. Therefore, we should be careful to only define those components that we will use. We must ask ourselves: "Should we put the component under the model space or not?" Certainly, the less components or widgets that we have in the model space, the better rendering performance we will experience.

The rendered versus the show attribute.

In some instances in your application, you may need to show and hide components. This can be achieved with the show attribute. If we set the value of this attribute to false, it will simply set the CSS styling display: none, thereby hiding the component. However, even when the component is hidden, the nodes will still be present in the browser. Once again, limiting the number of nodes rendered in the browser will improve application performance.

One way to achieve this performance improvement is to use the rendered attribute with the value set to false on a Backbase component. In this case, we should define in which part of the application do we want to optimize performance. The rendered attribute is best used when you want to improve the initial page loading time. This way, the page will be rendered when it is requested. On the other hand, this will reduce the delta communication performance. When it is needed, it will render all child elements, parse them, and then display the page. Compared with the rendered attribute, the show attribute has less delta communication performance, because the component does not need to be re-rendered when you want to display it. As a downside, the initial loading performance is less good however.

Example

<bjsf:listGrid id="sample-grid" markup="btl" rendered="false" binding="#{myBean.grid}" var="items" >
        <bjsf:column align="left" show="false">
                <f:facet name="header">
                        <bjsf:outputText value="Id" />
                </f:facet>
                <bjsf:outputText value="#{items.id}" />
        </bjsf:column>
        <bjsf:column align="left">
                <f:facet name="header">
                        <bjsf:outputText value="First Name" styleClass="colOne" />
                </f:facet>
                <bjsf:outputText value="#{items.firstName}" />
        </bjsf:column>
        <bjsf:column align="left">
                <f:facet name="header">
                        <bjsf:outputText value="Last Name" styleClass="colTwo" />
                </f:facet>
                <bjsf:outputText value="#{items.lastName}" />
        </bjsf:column>
        <bjsf:column align="left">
                <f:facet name="header">
                        <bjsf:outputText value="Email" />
                </f:facet>
                <bjsf:outputText value="#{items.email}" />
        </bjsf:column>
        <bjsf:column align="left">
                <f:facet name="header">
                        <bjsf:outputText value="Zip Code" />
                </f:facet>
                <bjsf:outputText value="#{items.zip}" />
        </bjsf:column>
</bjsf:listGrid>

Consider a listGrid with 5 columns listing 20 rows. According to the Reports tab in the Backbase Debugger tool, the Total text-nodes is 106 and the Total element-nodes is 223 when show is set to false. However, by setting rendered to false instead, the node count is dramatically reduced to 1 text node and 6 element nodes. The following example shows the generated code when the rendered attribute is implemented.

Example

<xmp backbase="true"
        xmlns="http://www.w3.org/1999/xhtml"
        xmlns:xi="http://www.w3.org/2001/XInclude"
        xmlns:b="http://www.backbase.com/2006/btl"
        xmlns:e="http://www.backbase.com/2006/xel"
        xmlns:c="http://www.backbase.com/2006/command"
        xmlns:bjsfc="http://www.backbase.com/2007/jsf/client"
        xmlns:bf="http://www.backbase.com/2007/forms">

        <div id="sample-grid" style="display:none" />
</xmp>

As you can see, by using the rendered attribute, it will create a hidden div and remove all of the child nodes from the component.

Static versus dynamic file inclusion

When files are loaded dynamically, they are not loaded when the view is initially constructed. Instead, they are loaded during application runtime, typically as a response to a user-driven event, such as a button click. Files that are included statically are loaded when the view is constructed.

It is important to consider application performance when choosing whether to load subviews during runtime, or statically include subviews during page construction. Static include files load faster than dynamically loaded files, but increase the initial page load time for information that the user may not necessarily need or even use. On the other hand, dynamic loading only loads components when necessary, but the user experience is decreased because of the latency at runtime.

Static file inclusion

<ul>
        <li><%@include file="myFragment.jsp"%></li>
        <li><jsp:include page="myFragment.jsp"/></li>
        <li><c:import url="myFragment.jsp"/></li>
        <li><xi:include/></li>
</ul>

Dynamic file inclusion

<ul>
        <li><bjsf:menuBar url="menu-items.jsp" /></li>
</ul>

In summary, both of these types of file inclusion have advantages and disadvantages. However, we can combine both of them in one application. We can use the dynamic file inclusion when we want to have faster initial loading page time. We can then use static file inclusion for any content that is accessed later on.

Bind the component

Binding a component will enable it to be automatically synchronized whenever it has been updated or manipulated. Component binding is recommended, since it does not require searching the entire server tree to find the component with the matching id.

Example

Component binding in JSP

<bjsf:inputText id="input01" value="bjsf:inputText" binding="#{myBean.input01}" />

Use plain HTML or a client widget for templating

It is often necessary to create a template for a page. This could be easily achieved using the <bjsf:panelset> <bjsf:panel> combination. However, in instances where the template is simply static and will not be changed or components will not be added to it, the best option is to use plain HTML <div/> and <table/>, since plain HTML markup will not be processed by the Backbase engine. Following this approach, the page will have a much lighter template than a <bjsf:panelSet/>.

Combine TDL definitions into one file

A common issue affecting the initial loading time occurs when you have many requests to the server. The Backbase config.xml is requested when the Backbase application is loaded. The config.xml is a configuration file that defines all the files used by Backbase. It will definitely increase the initial loading time, because it has to make many requests.

We advise a combination of all the TDL definitions into a single file. Keep in mind that you should combine the TDL definitions wisely. We recommended that you combine only the TDL definitions that are required by the page. For more information, refer to the Performance Tuning articles.

Remove unused components from the component tree

There may be a case where you must create a component that will only be used once, and will not be required anymore (for example, the components under the login view). The login is only used once in most applications. Therefore, it is better if the components under the login view are removed once the user passs the login credentials. This is because the server tree keeps track of all components. By decreasing the number of components in the server tree, the application will perform better.

Avoid using UIBBComponentBase.setStructureDirty(true) explicitly

The use of UIBBComponentBase.setStructureDirty(true) is not recommended. This will force the component and all of its children to be re-rendered or re-drawn, which will affect the response size. The component will automatically be re-render whenever there is a property, value or structure change, without having to set the structureDirty to true.