Professional Documents
Culture Documents
Overview
For any ADF/J2EE Java code, Model and UI layer, here are few points to make code better from writing from performance and standard point of view, that comes from our coding practice and experience. Here I have tried to consolidate a set of checkpoints we should check b4 checking in the source changes into SVN.This ensures making code better, robust, standards compatible and deliver good performant.
AM - Check Points
Number of occurances of createRootApplicationModule() or *AMImpl.getInstance() should be minimum. Use the appication module instance wisely.
ViewObject - CheckPoints
For new Attributes added, make sure you use proper UI hints. If creating a New VO, make sure its is based on an EO,unless required make RO VO. LOVs defined on parent VO shouldn't have "query automatically" checked.It degrades the performance Remove unwanted view accessors. Dont extend the impl classes unless required
Project - CheckPoints
Avoid cyclic dependency. Avoid dependency of the project on itself. Remove unwanted jars if attached.
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 tag. If you keep JavaScript and CSS in external files, they are cached by the browser. 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
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.
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. Both af:inputListOfValues and af:inputComboboxListOfValues are smart enough to load the list of values on demand(lazy loading) where asaf: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.
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.
ADF UI - Performance Tip: Lazy load task flows for better performance
Before discussing the performance improvement by implementing lazy loading for the task flows, let us go through the task flow basics.
How task flows are loaded normally? If you're dropping task flow as a region in your jsff, the task flow binding will be added in the pagedef file as an executable. So, anything under executables section including the task flows in pagedef file will be loaded by default when the jsff page is loaded.
ii. In the pagedef, set 'Activation' property for task flow binding to 'Conditional' and 'Active' property to above defined pageFlowScope variable with EL expression which evaluates to true when the popup is fetched.
2. For the hidden or conditionally rendered task flows: i. Conditionally rendered task flows will have the 'rendered' property set to some condition defined as EL expression based on which the region will be hidden or shown. You need to specify the same condition for the 'Active' property of the task flow binding in the pagedef. And, don't forget to set the 'Activation' property for task flow binding to 'Conditional'. Jsff containing taskflow: <af:showDetailHeader text="Emp Details" disclosed="true" id="sdh3"> <af:region value="#{bindings.ShowHideTaskFlow1.regionModel}" id="r2" rendered="#{pageFlowScope.showHideCondition==true}"/> </af:showDetailHeader>
The task flow in the corresponding pagedef file: <taskFlow id="ShowHideTaskFlow1" taskFlowId="/com/demo/taskflows/ShowHideTaskFlow.xml#ShowHideTas kFlow" activation="conditional" xmlns="http://xmlns.oracle.com/adf/controller/binding" active="#{pageFlowScope.showHideCondition==true}"/>
3. For panel tabs (af:panelTabbed) components i. Add a af:setPropertyListener of type 'disclosure' in each af:showDetailItem under af:panelTabbed and set some constant value to a pageFlowScope variable. You need to set value to the same pageFlowScope variable in each tab. On reading the pageFlowScope variable value, you should be able to tell in which you're currently in. Jsff containing taskflow: <af:panelTabbed id="pt1"> <af:showDetailItem id="showDetailItem1" text="Basic Details"> <af:region value="#{bindings.BasicDetailsTaskFlow1.regionModel}" id="region1"/> <af:setPropertyListener to="#{pageFlowScope.tabClicked}" type="disclosure" from="BASIC_DETAILS"/> </af:showDetailItem> <af:showDetailItem text="MainDetails" id="showDetailItem2"> <af:region value="#{bindings.MainDetailsTaskFlow1.regionModel}" id="region2"/> <af:setPropertyListener to="#{pageFlowScope.tabClicked}" type="disclosure" from="MAIN_DETAILS"/> </af:showDetailItem> <af:showDetailItem text="Other Details" id="showDetailItem3">