Monday, November 1, 2010

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.

How it impacts the performance?
As ADF loads all the task flows that are inlcuded in a page, even if they are not rendered by default, it'll be a performance hit as we're loading the task flows which are not needed by default. Examples below:
Popups: Task Flows on a popup should be loaded  only when user clicks on Pop-up link but ADF loads them during the page invocation itself and hence reduce the perfomrance of the page .
Hidden Taks Flows or Conditionally Rendered Task Flows: ADF page could have some of the task flows that are hidden based on a condition. In this scenario as well ADF loads the task flows during page loading even if those task flows are hidden and the model content in that will get executed during the page loads hence results in lower  performance of the page.
Panel Tabs: Page could have multiple tabs on a page with respective task flows , ADF loads all the task flows even though only one tab will be showed at a time.

So, What is lazy loading and how it improve the performance?
Lazy loading means loading the task flows only when they are required to be rendered. i.e., we won't load the task flows that are included inside popups, and those hidden initially, and the ones that are present in other than the default tab. We'll load them only when the popup is invoked, when the task flow region is unhidden/shown, on clicking the tab that has the task flow respectively.

How to implement lazy loading for the task flows?
1. For task flows in popups
i. Define a af:setPropertyListener of type 'popupFetch' and set some constant to one pageFlowScope variable.

<af:popup id="popup1" contentDelivery="lazyUncached"> <af:dialog id="dialog1" type="okCancel" title="Employee Details" inlineStyle="width:340px; height:125.0px;"> <af:panelGroupLayout id="panelGroupLayout1"> <af:region value="#{bindings.EmpDetailsTaskFlow1.regionModel}" id="r2"/> </af:panelGroupLayout> </af:dialog> <af:setPropertyListener to="#{pageFlowScope.popupFetched}" type="popupFetch" from="EMP_DETAILS"/> </af:popup>

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.
<taskFlow id="EmpDetailsTaskFlow1" taskFlowId="/com/demo/taskflows/EmpDetailsTaskFlow.xml#EmpDetailsTaskFlow" activation="conditional" xmlns="http://xmlns.oracle.com/adf/controller/binding" active="#{pageFlowScope.popupFetched=='EMP_DETAILS'}"/>

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#ShowHideTaskFlow" 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.


<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"> <af:region value="#{bindings.OtherDetailsTaskFlow1.regionModel}" id="region3"/> <af:setPropertyListener to="#{pageFlowScope.tabClicked}" type="disclosure" from="OTHER_DETAILS"/> </af:showDetailItem> </af:panelTabbed>

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 returns true when the tab containing that particular taskflow is clicked.
<taskFlow id="region1" taskFlowId="/com/demo/taskflows/BasicDetailsTaskFlow.xml#BasicDetailsTaskFlow" activation="conditional" xmlns="http://xmlns.oracle.com/adf/controller/binding" active="#{pageFlowScope.tabClicked=='BASIC_DETAILS'}"/> <taskFlow id="region2" taskFlowId="/com/demo/taskflows/MainDetailsTaskFlow.xml#MainDetailsTaskFlow" activation="conditional" xmlns="http://xmlns.oracle.com/adf/controller/binding" active="#{pageFlowScope.tabClicked=='MAIN_DETAILS'}"/> <taskFlow id="region3" taskFlowId="/com/demo/taskflows/OtherDetailsTaskFlow.xml#OtherDetailsTaskFlow" activation="conditional" xmlns="http://xmlns.oracle.com/adf/controller/binding" active="#{pageFlowScope.tabClicked=='OTHER_DETAILS'}"/>


That's quite simple. Now, your pages will load double faster than previous even with multiple task flow in your pages. Bingo :) !

16 comments:

  1. Hi,
    Thank you for lazy loading concept of taskfows, i am not able to succeed as adf controller is giving exception as below,

    oracle.adf.controller.ControllerException: ADFC-12014: Attempted access to an object that has already been released. Is there any thing I am missing ?

    ReplyDelete
  2. I am in the same situation of shankar!

    ReplyDelete
  3. @shankar and Ghepardo,
    Is it possible to send me a simple testcase? It'll help me to debug your issue.

    -Murali.

    ReplyDelete
  4. Unfortunately no :( The app is quite big. I opened an oracle support ticket for this.

    ReplyDelete
  5. I also get the same problem of "oracle.adf.controller.ControllerException: ADFC-12014: Attempted access to an object that has already been released." using this technique.

    Any clue what could be the problem?

    ReplyDelete
  6. I applied an example, It is really nice features, thank you Murali Papana ...

    ReplyDelete
  7. Worked perfectly, thanks.

    ReplyDelete
  8. Why did you append a "1" to the end of this expression?

    <af:region value="#{bindings.MainDetailsTaskFlow1.regionModel}"

    In you pageDef, you have it defined without the 1. I'm having trouble making the relationship between the pageDef file and the code inside the JSF.

    ReplyDelete
  9. Ok I was able to get this working great. However, I'm having a hard time figuring out how to configure the "default" tab. Because all tabs are set to load upon a click, my "default" tab is not being displayed at login until another tab is clicked, then you click back on the default tab.

    ReplyDelete
  10. Anyway we can prevent the content in and tab to be reloaded when we switch from one tab to another?

    ReplyDelete
  11. I have the same problem as this :
    Ok I was able to get this working great. However, I'm having a hard time figuring out how to configure the "default" tab. Because all tabs are set to load upon a click, my "default" tab is not being displayed at login until another tab is clicked, then you click back on the default tab.

    ReplyDelete
  12. To configure the "default" tab, set active="true" on taskFlow only default page :




    ReplyDelete
  13. For af:panelTabbed, there is property called , childCreation. If I set to 'lazy' , do I need to implement the above steps? Is it equivalent to above steps?

    ReplyDelete
  14. Erotika spa is offering multiple type of massage services, Body to Body Massage, Happy ending Massage, Erotic Massage, Sensual massage, B2b massage, Sandwich Massage, Swedish massage, Aroma oil Massage, tantra massage with price in Delhi, Female to male body Massage center in Delhi.

    Read More: https://femaletomalebodymassagecenter.in/

    ReplyDelete
  15. Private Hire Dublin Airport

    We provides best dublin taxi and shuttle services, such as getting our clients at airports, ports and train stations and giving support services at congresses, events and shows, besides organizing trips to the most varied destinations.

    A highlight of our activities is the City Tour – a dublin taxi service that takes our clients to any place inside or outside the city of Dublin, so they can get acquainted with what the city and the outskirts have the to offer at best.

    Besides the safety, quality and professionalism, we pride ourselves for the comfort we offer to our guests. We dedicate the upmost care to deliver to our clients the necessary well-being during their trip, counting with a modern fleet of vehicles to tend to their needs.

    Read More: https://www.easycab.ie

    ReplyDelete
  16. Elite SEO Agency is a reputed SEO Company in Melbourne, Australia offers it’s highly recommended strategic SEO services for local and national businesses, engaging Social Media Optimization and Marketing solution, effective PPC advertising campaigns, complete Digital Marketing solution and user-friendly web development and designing services to all range of businesses - small to mid sized.

    Contact now at +61-449650600 to get a Free SEO & Digital Marketing consultation with us!

    ReplyDelete

Related Posts with Thumbnails