Anda di halaman 1dari 3

Fine Tune ADF Faces UI Layer(Performance

Improvement)
Use AJAX to boost up the performance of your web pages
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
Mixing raw 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.
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.
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
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.
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(af:table, af:tree, af:treeTable), 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.
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.
we can disable ADF Faces Rich Client animation functionality globally, just by adding one line in trinidad-config.xml file:
animation-enabled = false
This will help greatly when rendering LOV popups, drawing data tables and etc. By disabling animation, artificial delay of components rendering is
removed and this allows to achieve better UI performance.
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 dont 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.
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
Use
Page templates
Declarative components
ADF task flows
Page Fragments
Use resource bundles intelligently
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.
Dont 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.
Always design your Managed Bean for High Availability
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.
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
ADF Faces provides a way to group (partitions) the JavaScript source files logically and down load each partition on demand.
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>