Fine Tune the View layer of your Fusion Web Application

Exclusive offer: get 50% off this eBook here
Oracle JRockit: The Definitive Guide

Oracle JRockit: The Definitive Guide — Save 50%

Develop and manage robust Java applications with Oracle's high-performance JRockit Java Virtual Machine with this Oracle book and eBook

$41.99    $21.00
by Jobinesh Purushothaman | July 2010 | Enterprise Articles Java Oracle

Oracle Application Development Framework (ADF) is an end to end enterprise application development framework built on Java and Java Platform Enterprise Edition (Java EE) technology stack. This is based on standard patterns and proven technologies, built with a motive of simplifying the technology complexity. Oracle ADF follows Model-View-Controller design (MVC) pattern, by adding definite roles to each layer.

A 'Fusion Web Application' is an enterprise web application built using ADF Faces for the view, ADF Model for data binding, and ADF Page Flow for the controller and ADF Business Components for business services. This article by Jobinesh Purushothaman, discusses basic guidelines on how to improve the performance and scalability of the view layer of a Fusion Web Application.

(For more resources on Oracle, see here.)

The following diadram illustrates the roles of each layer.

Oracle Application Development Framework (ADF)

Use AJAX to boost up the performance of your web pages

Asynchronous JavaScript and XML (AJAX) avoid the full page refresh and minimize the data that being transferred between client and server during each round trip. ADF Faces is packaged with 150+ AJAX enabled components which adds AJAX capability to your applications with zero effort. Certain events on an ADF Faces component trigger Partial Page Rendering (PPR) by default. However action components, by default, triggers full page refresh which is quite expensive and may not be required in most of the cases. Make sure that you set partialSubmit attribute to true whenever possible to optimize the page lifecycle. When partialSubmit is set to true, then only the components that have values for their partialTriggers attribute will be processed through the lifecycle.

Avoid mixing of html tags with ADF Faces components

Don’t mix html tags and ADF Faces components though JSF design let you to do so using <f:verbatim> tag. Mixing row html contents with ADF Faces components may produce undesired output, especially when you have complex layout design for your page. It's highly discouraged to use <f:verbatim> to embed JavaScript or CSS, instead you can use <af:resource> which adds the resource to the document element and optimizes further processing during tree rendering.

Avoid long Ids for User Interface components

It's always recommended to use short Ids for your User Interface (UI) components. Your JSF page finally boils down to html contents, whose size decides the network bandwidth usage for your web application. If you use long Ids for UI (User Interface) component, that increases the size of the generated html content. This becomes even worse, if you have many UI elements with long Ids.

If there's no Id is set for a UI component explicitly, ADF Faces runtime auto generates Ids for you. ADF Faces let you to control the auto generation of component ids by setting context parameter 'oracle.adf.view.rich.SUPPRESS_IDS' in the web.xml file. The <context-param> entry in the web.xml file may look like as shown below.

<context-param>
<param-name>
oracle.adf.view.rich.SUPPRESS_IDS
</param-name>
<param-value>auto or explicit </param-value>
</context-param>

Possible values for oracle.adf.view.rich.SUPPRESS_IDS are listed below.

  • auto: Components can suppress auto generated IDs, but explicitly set ID will be honored.
  • explicit: This is the default value for oracle.adf.view.rich.SUPPRESS_IDS parameter. In this case both auto generated IDs and explicitly set IDs would get suppressed.

Avoid inline usage of JavaScript/Cascading Style Sheets (CSS) whenever possible

If you need to use custom JavaScript functions or CSS in your application, try using external files to hold the same. Avoid inline usage of JavaScripts/CSS as much as possible. A better idea is to logically group them in external files and embed the required one in the candidate page using <af:resource> tag. If you keep JavaScript and CSS in external files, they are cached by the browser. Apparently, subsequent requests for these resources are served from the cache. This in turn reduces the network usage and improves the performance.

Avoid mixing JSF/ADF Faces and JavaServer Pages Standard Tag Library (JSTL) tags

Stick on JSF/ADF Faces components for building your UI as much as you can. JSF component may not work properly with some JSTL tags as they are not designed to co-exist. Relying on JSF/ADF Faces components may give you better extensibility and portability for your application as bonus.

Don't generate client component unless it's really needed

ADF Faces runtime generates the client components only when they are really required on the client. However you can override this behavior by setting the attribute clientComponent to true, as shown in the following code snippet.

<af:commandButton text="DoSomething" clientComponent="true">
<af:clientListener method="doSomething" type="action"/>
</af:commandButton>

Set clientComponent to true only if you need to access the component on the client side using JavaScript. Otherwise this may result in increased Document Object Model (DOM) size at the client side and may affect the performance of your web page. The following diagram shows the runtime coordination between client side and server side component trees.

Oracle Application Development Framework (ADF)

In the above diagram, you can see that no client side component is generated for the server component whose clientComponent attribute is set to false.

Prefer not to render the components over hiding components from DOM tree

If you need to hide UI components conditionally on a page, try achieving this with rendered property of the component instead of using visible property. Because the later creates the component instance and then hides the same from client side DOM tree, where as the first approach skips the component creation at the server side itself and client side DOM does not have this element added. Apparently setting rendered to false, reduces the client content size and gives better performance as bonus.

Oracle JRockit: The Definitive Guide Develop and manage robust Java applications with Oracle's high-performance JRockit Java Virtual Machine with this Oracle book and eBook
Published: June 2010
eBook Price: $41.99
Book Price: $69.99
See more
Select your format and quantity:

(For more resources on Oracle, see here.)

Prefer to use click-To-Edit over edit-All mode for tables

The click-To-Edit mode table lets the end user to edit the selected rows in a lockstep fashion, one row at a time. Advantages of using click-To-Edit mode are listed below.

  • In a click-To-Edit, non editable rows are rendered as output components which tend to generate less HTML than input components.
  • Client components are not created for the read-only rows.
  • Validation phase is also optimized to handle one row at a time.
  • Request and Response data is significantly lower in this mode as data relevant to the current editable row alone is being transferred between client and server. Really a good option if the table has large number of rows.

Fine tune the UI tables, displayed on your web page

  • Use appropriate content delivery mode
    Pick up the suitable content delivery mechanism for your UI table to accelerate the performance. Data can be delivered to table either upon rendering the page or lazily as separate Partial Page Request (PPR). This behavior is controlled by the contentDelivery attribute. Possible values for this attribute are:
    • immediate
    • lazy
    • whenAvailable

    If the page contains only the table context or the number of rows displayed are low (say 50 or below) use immediate delivery. You can opt for lazy delivery when the page contains a number of components other than a table or if the number of rows filled is on the higher side.

  • Use suitable fetch size
    Data fetch size for a table plays critical role in deciding the performance of the containing pages. The attribute fetchSize decides the number of rows needs to be retrieved during each server round trip. You may need to ensure that value specified for this attribute is good enough to fill the displayed table rows to avoid further server round trips.

The above discussion is applicable for tree and tree table as well.

Pickup right component to display list of values (LOV)

ADF Faces provides multiple components or modes to display the 'list of values'. You may need to choose the right one based on your business requirements.

List Type

Component

Input Text with List of Values

af:inputListOfValues

Combo Box with List of Values

af:inputComboboxListOfValues

Choice List, Combo Box, List Box, Radio Group

af:selectOneChoice

Both af:inputListOfValues and af:inputComboboxListOfValues are smart enough to load the list of values on demand(lazy loading) where as af:selectOneChoice reads the entire list and populates the same when the page renders(greedy loading). You need to me be aware of the performance cost associated with each of these components. As a rule of thumb, consider af:selectOneChoice to display the list of values if the number of elements is less (say 15 or less) .In all other cases consider using either af:inputListOfValues or af:inputComboboxListOfValues, which loads list on demand.

Use customized Skins to style your pages

If you need to specify custom styles (look and feel) such as height, width, font size etc. for components on a page, then use ADF Faces skinning solution. Though you can do this by overriding inline style for each component, this may not be a viable solutions if this style needs to be applied across pages. ADF Faces always lets you to override the default look and feel for a component by creating custom skins. Skinning let you to override the look and feel of UI components across application. If you need to apply the style to a specific group of components alone, then you can create a style class with standard selector(s), and apply them by setting the styleClass attribute of the component to the desired style class.

Choose the right layouts to design your pages

While lay outing components on page, choose the right layout component that meets your requirement. If you don’t want stretch-to-fit layout, then dot use them at all. A stretch-to-fit layout is not as good performant as fixed height-width layouts. Situation becomes worse, if you have nested containers with many child UI components inside. Apart from these geometry management components, there are certain attributes which may need special attention on the same context. You may need to be measured while opting for columnStretching property for a table to stretch the column to fit the available width. The columnStretching adds extra overhead on the client side at runtime. When the table is a complex one with large number of columns and rows, this becomes very expensive operation. The same point is applicable for table with frozen columns (frozen=true), they are also expensive on the client side.

Avoid repetitive coding by improving the reusability

When you build an application, avoid replicating the same piece of code or component definitions across pages. ADF Faces is built focusing on maximum reusability and minimal boiler plate code. Consider one of the approaches explained below, to improve the reusability in your application.

  • Page templates
    Page template helps you to keep generic page definition in one place and reuse the same as basis for building pages and page fragments. New pages generated based on the page template inherit the layout defined for the page template and these pages can add the custom contents in the place holders provided by the template. You may need to be cautious while choosing layout for page template as this repeats across multiple pages in your application. Try to keep the layout simple and efficient.
  • Declarative components
    The declarative components follows composite design pattern, where you can assemble individual UI components into one composite reusable component. The same can be used declaratively in multiple pages. This really helps you to build complex reusable UI by composing multiple components. Declarative components can also be used in page templates.
  • ADF task flows
    Task flows provide a modular approach for defining control flow in an application. If you have use case which involves multiple tasks that needs to be carried out in a step by step manner, apparently that turns out to a perfect candidate for a 'task flow'. Task flow encapsulates business logic, process flow, and UI components all in one package, which can then be consumed by multiple teams declaratively.
  • Page Fragments
    If you page is cluttered with huge chunk of UI components and the same repeats across pages in your application, try considering creating reusable page fragments and later consume them from the client pages. A page fragment, as the name stands represents portion of page embedded inside <jsp:root> tag.

Use resource bundles intelligently

Success of a product depends on its marketability across the globe. Obviously, localization of messages and labels play a very vital role in this context. As you use Java for building fusion web application, you may need to use java.util.ResourceBundle to store locale specific objects like messages or labels. A couple of points on the effective usage of ResourceBundles are listed below.

  • If the size of your resource bundle is huge, logically split that into multiple resource bundles. While splitting, please make sure that a single page doesn't need to look in to multiple bundles to get the localized strings.
  • Don’t over engineer your product by caching the ResourceBundle in your managed bean or through a custom way, it's already cached for you by design.

Be bold enough to bypass the JSF lifecycle phases as and when needed

The JSF lifecycle is not trivial; each request is routed through definite stages before rendering the page. However there are scenarios where you can bypass certain phases and leverage some performance bonus. While navigating from one page to another, using navigation components, there is no need to stick on the full JSF life cycle. You can short circuit the lifecycle phases by keeping immediate=true for navigation/action components. You can see this in the following diagram that life cycle execution skips to RenderResponse phase when immediate property set as true for an action button.

Oracle Application Development Framework (ADF)

Please note that, you can skip to the RenderResponse phase by calling javax.faces.context.FacesContext::renderResponse() from any phase of execution.

Always design your Managed Bean for High Availability

Managed Beans are very essential elements for a JSF based application. They act as back up for UI component model and can hold view specific custom business logic as well. There are six types of scopes available for managed beans in a fusion web application as listed in the below diagram.

Oracle Application Development Framework (ADF)

You may need to take care of following points in regards to managed bean while developing a high available fusion web application.

  • Keep the managed beans in the lowest possible scope
    While defining managed bean always try to keep them in the lowest possible scope, which reduces the runtime overhead associated with state replication across nodes in a clustered environment.
  • Keep the getters/setters of your managed bean (data model) lightweight
    You may need to understand that getters and setters for a managed bean used in a page may get called multiple times during the life cycle. Always make sure that assessors specified for the data model doesn't have any complex logic. Use managed bean only to store book keeping information, business logic should reside in your business service layer.
  • Bean should be serializable
    If the managed bean scope is higher than request, then its state needs to be serialized and copied to other nodes at the end of each request. Obviously beans need to implement java.io.Serializable interface. Note that, member variable of you class should also be serializable, or marked as transient if their state does not need to be replicated at the end of a request.
  • Mark ADF scopes as dirty to enable state replication
    ADF optimizes state replication of ADF scoped beans to avoid the blind copy of the state at the end of each request. So you may need to ask for state replication by marking them as dirty, based on bean mutation state. Use the below API to ensure the state replication for viewScope or pageFlowScoped bean if its modified for any request.
    ControllerContext.getInstance().markScopeDirty(viewScope/pageFlowScope);

Log your debugging messages smartly with ADFLogger

It's a bad practice to use System.out.println() to log your debugging or diagnostic messages. There is no easy way to turn off or control these logs when your application goes for production. This may dump all unwanted logs in your application server, adding extra overhead for your system administrator. If the numbers of logs statements are large in number, this may affect your system's runtime performance too. For fusion web application, it is recommended to use oracle.adf.share.logging. ADFLogger to log all debugging messages which gives more control on the logging part. You can easily change log levels (turn off or customize) of ADFLogger using the configuration parameters present in logging.xml.

Feel free to override the default rules set for JavaScript Partitioning

Almost all html based web frameworks make use of heavy JavaScript based libraries to set up the basic infrastructure at the client side. Apart from these core run time libraries, an enterprise application may have its own custom JavaScript libraries. ADF Faces provides a way to group (partitions) the JavaScript source files logically and down load each partition on demand. The default partitioning provided by ADF Faces may not be ideal for your application in all cases; it depends upon the combination of UI components used to build pages and usage pattern of the pages. ADF Faces allows you to tune the JavaScript library footprint to meet the needs of their application. You can override the default partition rules (that come with ADF Faces) by creating your own adf-js-partitions.xml in the WEB-INF directory.

Speed up your web application by caching static contents

Caching static contents such as images, JavaScript, css etc. improves performance of the system. ADF Faces is packaged with oracle.adf.view.rich.webapp.AdfFacesCachingFilter (servlet filter) which marks the application resources for caching at external Web Cache and/or user-agents (browsers). ADF Faces comes with set of default rules for caching static contents; however developers can override the default caching behavior with application's adf-config.xml file. This file is located under your web application's WEB-INF folder. Following diagram shows the syntax for defining caching rules in adf-config.xml.

<?xml version="1.0" encoding="windows-1252" ?>
<adf-config xmlns="http://xmlns.oracle.com/adf/config"
xmlns:adf="http://xmlns.oracle.com/adf/config/properties"
xmlns:sec="http://xmlns.oracle.com/adf/security/config">
<adf-faces-config xmlns="http://xmlns.oracle.com/adf/faces/config">
<caching-rules>
<caching-rule id="cache js">
<cache>true</cache>
<compress>true</compress>
<duration>99999</duration>
<agent-caching>true</agent-caching>
<cache-key-pattern>*.js</cache-key-pattern>
</caching-rule>
<caching-rule id="cache jpeg">
<cache>true</cache>
<compress>false</compress>
<duration>99999</duration>
<agent-caching>true</agent-caching>
<cache-key-pattern>*.jpeg</cache-key-pattern>
</caching-rule>
</caching-rules>
</adf-faces-config>
</adf-config>

Summary

In this article, we have learned tips on how to improve the performance and scalability of the view layer of a Fusion Web Application.

References


Further resources on this subject:


BPEL PM and OSB operational management with Oracle Enterprise Manager 10g Grid Control Oracle Enterprise Manager 10g Grid Control - Manage the operational tasks for multiple Oracle BPEL and OSB environments centrally using this book and eBook
Published: August 2010
eBook Price: $26.99
Book Price: $44.99
See more
Select your format and quantity:

About the Author :


Jobinesh Purushothaman is an enterprise Java specialist with 11+ years of experience in the industry. He works with Oracle as Principal Product Manager for Application Development Framework (ADF). He is involved in design and architectural decisions of various products using ADF and Java EE technologies. He has been mentoring and training developers on ADF and related Java technologies for last few years. Links to his articles may be found at jobinesh.blogspot.com

.

Books From Packt


Middleware Management with Oracle Enterprise Manager Grid Control 10g R5
Middleware Management with Oracle Enterprise Manager Grid Control 10g R5

Web 2.0 Solutions with Oracle WebCenter 11g
Web 2.0 Solutions with Oracle WebCenter 11g

Oracle SOA Suite 11g R1 Developer's Guide
Oracle SOA Suite 11g R1 Developer's Guide

The Oracle Universal Content Management Handbook
The Oracle Universal Content Management Handbook

Oracle SQL Developer 2.1
Oracle SQL Developer 2.1

Oracle Application Express 3.2 - The Essentials and More
Oracle Application Express 3.2 - The Essentials and More

Oracle 11g R1 / R2 Real Application Clusters Handbook
Oracle 11g R1 / R2 Real Application Clusters Handbook

Oracle Database 11g – Underground Advice for Database Administrators
Oracle Database 11g – Underground Advice for Database Administrators


Your rating: None Average: 5 (6 votes)
Really informative by
The article is really intresting and useful for Java and Java EE application developers,, the amusing in depth knowledge of the author enlighten the reader thoughts to a new level towards Oracle Application Development Framework. A wonderful article !!!!

Post new comment

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.
h
v
j
8
i
L
Enter the code without spaces and pay attention to upper/lower case.
Code Download and Errata
Packt Anytime, Anywhere
Register Books
Print Upgrades
eBook Downloads
Video Support
Contact Us
Awards Voting Nominations Previous Winners
Judges Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software
Resources
Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software