Tuesday, March 8, 2011

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.

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:

The task flow in the corresponding pagedef file:

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.

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.

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

No comments:

Post a Comment