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.

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.

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.

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.

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.

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 modePick 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 sizeData 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 templatesPage 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 componentsThe 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 flowsTask 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 FragmentsIf 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.

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.

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 scopeWhile 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) lightweightYou 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 serializableIf 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 replicationADF 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.

Alerts & Offers

Series & Level

We understand your time is important. Uniquely amongst the major publishers, we seek to develop and publish the broadest range of learning and information products on each technology. Every Packt product delivers a specific learning pathway, broadly defined by the Series type. This structured approach enables you to select the pathway which best suits your knowledge level, learning style and task objectives.

Learning

As a new user, these step-by-step tutorial guides will give you all the practical skills necessary to become competent and efficient.

Beginner's Guide

Friendly, informal tutorials that provide a practical introduction using examples, activities, and challenges.

Essentials

Fast paced, concentrated introductions showing the quickest way to put the tool to work in the real world.

Cookbook

A collection of practical self-contained recipes that all users of the technology will find useful for building more powerful and reliable systems.

Blueprints

Guides you through the most common types of project you'll encounter, giving you end-to-end guidance on how to build your specific solution quickly and reliably.

Mastering

Take your skills to the next level with advanced tutorials that will give you confidence to master the tool's most powerful features.

Starting

Accessible to readers adopting the topic, these titles get you into the tool or technology so that you can become an effective user.

Progressing

Building on core skills you already have, these titles share solutions and expertise so you become a highly productive power user.