Skip Headers
Oracle® Fusion Middleware Performance and Tuning Guide
11g Release 1 (11.1.1.7.0)

Part Number E10108-13
Go to Documentation Home
Home
Go to Book List
Book List
Go to Table of Contents
Contents
Go to Index
Index
Go to Master Index
Master Index
Go to Feedback page
Contact Us

Go to previous page
Previous
Go to next page
Next
PDF · Mobi · ePub

8 Oracle Application Development Framework Performance Tuning

This chapter provides basic guidelines on how to maximize the performance and scalability of the Oracle Application Development Framework (ADF). This chapter covers design, configuration, and deployment performance considerations in the following sections:

This chapter assumes that you are familiar with building ADF applications. To learn about ADF, see the following guides:

8.1 About Oracle ADF

Oracle Application Development Framework (Oracle ADF) is an end-to-end application framework that builds on Java Platform, Enterprise Edition (Java EE) standards and open-source technologies to simplify and accelerate implementing service-oriented applications. Oracle ADF is suitable for enterprise developers who want to create applications that search, display, create, modify, and validate data using web, wireless, desktop, or web services interfaces.

For more information see "Introduction to Oracle ADF" in Oracle Application Development Framework Developer's Guide.

8.2 Basic Tuning Considerations

Before building, configuring, and deploying ADF applications, review the following tuning recommendations to achieve optimal performance:

8.2.1 Oracle ADF Faces Configuration and Profiling

This section discusses the configuration and profiling concepts of the ADF Faces. Configuration options for Oracle ADF Faces are set in the web.xml file. Most of parameters have default values that can be tuned for performance. Table 8-1 describes some of these configuration options.

Table 8-1 ADF Configuration Options

Parameter Description

Compress View State

org.apache.myfaces.trinidad.COMPRESS_VIEW_STATE

Controls whether or not the page state is compressed. Latency can be reduced if the size of the data is compressed. The default is False, but to optimize performance, consider setting this parameter to True.

Debug Mode

org.apache.myfaces.trinidad.resource.DEBUG

Controls whether output should be enhanced for debugging or not. This parameter should be removed or set to False.

Check File Modification

org.apache.myfaces.trinidad.resource.CHECK_FILE_MODIFICATION

Controls whether ADF faces check for modification date of JSP pages and discard any saved state if the file is changed. This parameter should be removed or set to False.

Client State Method

oracle.adf.view.rich.CLIENT_STATE_METHOD

Specifies which type of saving (all or token) should be used when client-side state saving is enabled. The default value is token. Consider using token to optimize performance.

Log Level

oracle.adf.view.rich.LOGGER_LEVEL

Sets the log level on the client side. The default value is OFF. This parameter should be removed or set to OFF.

Assert Enabled

oracle.adf.view.rich.ASSERT_ENABLED

Specifies whether to process assertions on the client side. The default value is OFF. This parameter should be removed or set to OFF.


Note:

When you are profiling or measuring client response time using the Firefox browser, ensure that the Firebug plug-in is disabled. While this plug-in is very useful for getting information about the page and for debugging JavaScript code on the page, it can impact the total response time.

For more information on disabling the Firefox Firebug plug-in, see the Firefox Support Home Page at http://support.mozilla.com/en-US/kb/.

8.2.2 Tuning ADF Faces

Table 8-2 provides configuration recommendations that may improve performance of ADF Faces:

Table 8-2 Configuration Parameters for ADF Faces

Configuration Recommendation Description

Avoid inline JavaScript in pages.

Inline JavaScript can increase response payload size, will never be cached in browser, and can block browser rendering. Instead of using inline JavaScript, consider putting all scripts in .js files in JavaScript libraries and add scripts to the page using af:resource tag.

NOTE: Consider using af:resource rather than trh:script when possible.

Avoid self-signed SSL certificates. Opt for officially signed security certificates instead.

In some browsers, using a self-signed SSL certificate prevents resources from being cached. The resources, such as JavaScript libraries, images, and style sheets, must be reloaded each time a user accesses the application, which can impact network performance.

An added benefit of using officially-signed SSL certificates is the additional security assurances they can provide over self-signed certificates.

Configure the JSP timeout parameter.

Using the JavaServer Pages (JSP) timeout parameter causes infrequently used pages to be flushed from the cache by the following setting in web.xml:

<servlet> 
  <servlet-name>
     oraclejsp
     <init-param>
      <param-name>
       jsp_timeout
      </param-name>
      <param-value>
        600
     </param-value>
    </init-param>
  </servlet-name>
</servlet> 

NOTE: Set this parameter based on your own use case scenarios.

Create a single toolbar item with a drop-down popup.

When the browser size is small because of the screen resolution, the menubar/toolbar overflow logic becomes expensive in Internet Explorer 7 and 8. It especially has problems with laying out DOM structures with command items.

Create a single toolbar item with a drop-down popup and put all the input fields inside it. This popup should have deferred child creation and contentDelivery="lazy".

Use shared popups in collection-based components (like table).

Stamping popups in a table can impact performance, so consider using a shared popup in collection-based components (like table) to reduce the overhead.

Do not use hover popups on navigation links.

A hover popup on a navigation link causes the navigation to wait for the hover to be fetched first.

Move hover popups on navigation links in a table to a separate icon within the table cell

Use partial page navigation.

Partial Page Navigation is a feature of the ADF Faces framework that enables navigating from one ADF Faces page to another without a full page transition in the browser.The new page is sent to the client using Partial Page Rendering (PPR)/Ajax channel.

The main advantage of partial page navigation over traditional full page navigation is improved performance: the browser no longer re-interprets and re-executes Javascript libraries, and does not spend time for cleanup/initialization of the full page. The performance benefit from this optimization is very big; it should be enabled whenever possible.

Some known limitations of this feature are:

  • For the document's "metaContainer" facet (the HEAD section), only scripts are brought over with the new page. Any other content, such as icon links or style rules can be ignored.

  • Applications cannot use anchor (hash) URLs for their own purposes.

For more information, see "Using Partial Page Navigation" in the Oracle Fusion Middleware Web User Interface Developer's Guide for Oracle Application Development Framework.

Use page templates.

Page templates enable developers to build reusable, data-bound templates that can be used as a shell for any page. A developer can build one or more templates that provide structure and consistency for other developers building web pages. The templates have both static areas on them that cannot be changed when they are used and dynamic areas on them where the developer can place content specific to the page they are building.

There are some important considerations when using templates:

  • Since templates are present in every application page, they have to be optimized so that common performance impacts are avoided. Adding round corners to the template, for example, can impact the performance for every page.

  • When building complex templates, avoid building them in multiple pieces and including them in the top-level template using <f:subview> tag. From a performance perspective, doing so can impact memory usage on the server side. (<f:subview> introduces another level into the ID scoping hierarchy, which results in longer IDs. Long IDs have a negative impact on performance. Developers are advised to avoid using <f:subview> unless it is required. It is not necessary to use <f:subview> around <jsp:include> if you can ensure that all IDs are unique. For example, if you are using <jsp:include>, break a large page into multiple pieces for easier editing. And whenever possible, avoid using <f:subview>. If you are including content developed by someone else, use <f:subview> if you do not know which IDs the developer used. In addition, you do not have to put <f:subview> at the top of a region definition.

  • Avoid long IDs in all cases, especially on pageTemplates, subviews, subforms, and on tables or within tables. Long IDs can have a performance impact on the server side, network traffic, and client processing.

For more information, see the topic "Using Page Templates" in Oracle Fusion Middleware Web User Interface Developer's Guide for Oracle Application Development Framework.

Enable ADF faces geometry management.

ADF Rich Client supports geometry management of the browser layout where parent components are in the UI explicitly. The children components are sized to stretch and fill up available space in the browser. While this feature makes the UI look better, it has a cost. The impact is on the client side where the browser must spend time resizing the components. The components that have geometry management by default are:

  • PanelGridLayout

  • PanelAccordion

  • PanelStretchLayout

  • PanelTabbed

  • BreadCrumbs

  • NavigationPane

  • PanelSplitter

  • Toolbar

  • Toolbox

  • Table

  • Train

Notes:

  • Consider using panelGridLayout to flatten HTML hierarchy and improve performance when designing page layouts for non-stamped component. panelGridLayout uses JavaScript to accomplish page layout like PSL, but it does not have the overheard of nesting JS layout components.

    To avoid performance degradation, do not use PanelGridLayout in stamped components

  • When using geometry management, try minimizing the number of child components that are under a parent geometry managed component.

  • The cost of geometry management is directly related to the complexity of child components.

  • The performance cost of geometry management can be smaller (as perceived by the user) for the pages with table or other data stamped components when table data streaming is used. The client-side geometry management can be executed while the browser is waiting for the data response from the server.

For more information, see the topic "Geometry Management and Component Stretching" in Oracle Fusion Middleware Web User Interface Developer's Guide for Oracle Application Development Framework.

Use the ADF rich client overflow feature.

ADF Rich Client supports overflow feature. This feature moves the child components to the non-visible overflow area if they cannot fit the page. The components that have built-in support for overflow are: PanelTabbed, BreadCrumbs, NavigationPane, PanelAccordion, Toolbar, and Train. Toolbar should be contained in a Toolbox to handle the overflow.

While several optimizations methods are in place to reduce the cost of overflow, it is necessary to pay special attention to the number of child components and complexity of each of them in the overflow component. Consider setting a big enough initial size of the overflow component so that overflow does not happen in most cases.

To prevent performance degradation, however, consider adding a drop-down with the command items to avoid these overflow areas.

Use ADF Rich Client Partial Page Rendering (PPR).

ADF Rich Client is based on Asynchronous JavaScript and XML (Ajax) development technique. Ajax is a web development technique for creating interactive web applications, where web pages feel more responsive by exchanging small amounts of data with the server behind the scenes, without the whole web page being reloaded. The effect is to improve a web page's interactivity, speed, and usability.

With ADF Faces, the feature that delivers the Ajax partial page refresh behavior is called partial page rendering (PPR). PPR enables small areas of a page to be refreshed without having to redraw the entire page. For example, an output component can display what a user has chosen or entered in an input component or a command link or button can cause another component on the page to be refreshed.

Two main Ajax patterns are implemented with partial page rendering (PPR):

  • native component refresh

  • cross-component refresh

While the framework builds in native component refresh, cross-component refresh has to be done by developers in certain cases.

Cross-Component refresh is a concept where different components on the page have a semantic relationship to one an other. For example, if a user selects one choice component on a page that prompts a country selection. The outcome of this selection requires another component on the page to be changed and updated to show the valid states of the country. This relationship requires a cross-component refresh. This can be accomplished either declarative or programmatically. For more information, refer to Oracle Fusion Middleware Fusion Developer's Guide for Oracle Application Development Framework).

It is important to note the differences between partial targets and partial triggers when using cross-component refresh. Partial triggers are used when a component wants to listen for changes on another component. Partial targets are used when a component that changes wants to make sure other components on the page are re-rendered.

Consider a typical situation in which a page includes an af:inputText component, an af:commandButton component, and an af:outputText component. When the user enters a value for the af:inputText, then clicks the af:commandButton, the input value is reflected in the af:outputText. Without PPR, clicking the af:commandButton triggers a full-page refresh. Using PPR, you can limit the scale of the refresh to only those components you want to refresh, in this case the af:outputText component. To achieve this, you would do two things:

  • Set up the af:commandButton for partial submit by setting the partialSubmit attribute to true. Doing this causes the command component to start firing partial page requests each time it is clicked.

  • Define which components are to be refreshed when the partial submit takes place, in this example the af:outputText component, by setting the partialTriggers attribute for each of them to the id of the component triggering the refresh. In this example, this means setting the partialTriggers attribute of the af:outputText component to give the id of the af:commandButton component.

The steps above achieve PPR using a command button to trigger the partial page refresh.

The main reason why partial page rendering can significantly boost the performance is that full page refresh does not happen and the framework artifacts (such as ADF Rich Client JS library, and style sheets) are not reloaded and only a small part of page is refreshed. In several cases, this means no extra data is fetched or no geometry management.

The ADF Rich Client has shown that partial page rendering results in the best client-side performance. Besides the impact on the client side, server-side processing can be faster and can have better server-side throughput and scalability.

For more information, see the topic "Rerendering Partial Page Content" in Oracle Fusion Middleware Web User Interface Developer's Guide for Oracle Application Development Framework.

Use ADF rich client navigation.

ADF Rich Client has an extensive support for navigation. One of the common use cases is tabbed navigation. This functionality is currently supported by components like navigationPane which can bind to xmlMenuModel to easily define navigation.

There is one drawback in this approach, however. Using ADF rich client navigation results in a full page refresh every time the user switches the tab. One option is to use panelTabbed instead. panelTabbed has built-in support for partial page rendering of the tabbed content without requiring any developer work. However, panelTabbed cannot bind to any navigational model and the content has to be available from within the page, so it has limited applicability.

Cache resources.

Developers are strongly encouraged to ensure that any resources that can be cached (images, CSS, JavaScript) have their cache headers specified appropriately. Also, client requests for missing resources on the server result in addition round trips to the server. To avoid this, make sure all the resources are present on the server.

Consider using the ResourceServlet to configure web.xml to enable resource caching:

<servlet-mapping>
     <servlet-name>resources</servlet-name>
     <url-pattern>/js/*</url-pattern>
   </servlet-mapping>
<servlet-mapping>
     <servlet-name>resources</servlet-name>
     <url-pattern>/images/*</url-pattern>
   </servlet-mapping> 

Reduce the size of state token cache.

This property is defined in web.xml org.apache.myfaces.trinidad.CLIENT_STATE_MAX_TOKENS in "token"-based client-side state saving and determines how many tokens should be preserved at any one time. The default value is 15. When this value is exceeded, state will be "forgotten" for the least recently viewed pages, which can impact users that actively use the Back button or that have multiple windows open simultaneously.

In order to reduce live memory per session, consider reducing this value to 2. Reducing the state token cache to 2 means one Back button click is supported. For applications without support for a Back button, this value should be set to 1.

CAUTION: Setting this parameter to 1 is not recommended for Oracle WebCenter applications as it may cause the JSP error IllegalStateException. For example, WebCenter Spaces and WebCenter Framework Portal applications launch dialog windows, implying that the previous state of the JSF view tree has to be stored. If the number is set to 1, then the system can store the current main view page and then view the dialog page when viewing a mail, for example. The dialog page is now trying to open another dialog page (for reply or forward), but the server cannot save the state of the previous page and returns the IllegalStateException.

Use af:resource component to deliver css and js scripts.

A common developer task is to define custom styles inside a regular page or template page. Since most browsers use progressive scanning of the page, a late introduction of styles forces the browser to recompute the page. This impacts the page layout performance. For better performance use af:resource component to deliver css and js scripts.

To get a component (or static CDATA content) to display in the "head", use the "metaContainer" facet.

See the Oracle Fusion Middleware Fusion Developer's Guide for Oracle Application Development Framework for details about af:facetRef.

Optimize custom JavaScript code.

ADF Rich Client uses JavaScript on the client side. The framework itself provides most of the functionality needed. However, you may have to write custom JavaScript code. To get the best performance, consider bundling the JavaScript code into one JS lib (one JavaScript file) and deliver it to the client. The easiest approach is to use the ADF tag: <af:resource type="javascript" source=" "/>.

If most pages require custom JavaScript code, the tag should be included in the application template. Otherwise, including it in particular pages can result in better performance. If custom the JavaScript code lib file becomes too big, then consider splitting it into meaningful pieces and include only the pieces needed by the page. Overall, this approach is faster since the browser cache is used and the html content of the page is smaller.

Disable debug output mode.

The debug-output element in the trinidad-config.xml file specifies whether output should be more verbose to help with debugging. When set to TRUE, the output debugging mechanism in Trinidad produces pretty-printed, commented HTML content. To improve performance by reducing the output size, you should disable the debug output mode in production environments.

Set the debug-output element to FALSE, or if necessary, remove it completely from the trinidad-config.xml file.

Disable test automation.

Enabling test automation parameter oracle.adf.view.rich.automation.ENABLED generates a client component for every component on the page which can negatively impact performance.

Set the oracle.adf.view.rich.automation.ENABLED parameter value to FALSE (the default value) in the web.xml file to improve performance.

Disable animation.

ADF Rich Client framework has client side animation enabled by default. Animation is introduced to provide an enhanced user experience. Some of the components, like popup table, have animation set for some of the operations. While using animation can improve the user experience, it can increase the response time when an action is executed. If speed is the biggest concern, then animation can be disabled by setting the flag in trinidad-config.xml

Disable client-side assertions.

Assertions on client-side code base can have a significant impact on client-side performance. Set the parameter value to FALSE (the default value) to disable client-side assertions. Also ensure that the oracle.adf.view.rich.ASSERT_ENABLED is not explicitly set to TRUE in the web.xml file.

Disable JavaScript Profiler.

When the JavaScript oracle.adf.view.rich.profiler.ENABLED profiler is enabled, an extra round-trip occurs on every page in order to fetch the profiler data. Disable the profiler in the web.xml file to avoid this extra round-trip. Default is DISABLED.

Disable resource debug mode.

When resource debug mode is enabled, the HTTP response headers do not tell the browser (or WebCache) that resources (JS libraries, CSS style sheets, or images) can be cached.

Disable the org.apache.myfaces.trinidad.resource.DEBUG parameter in the web.xml file to ensure that caching is enabled.

Disable timestamp checking.

The org.apache.myfaces.trinidad.CHECK_FILE_MODIFICATION parameter controls whether jsp or jspx files are checked for modifications each time they are accessed.

Ensure that the parameter value org.apache.myfaces.trinidad.CHECK_FILE_MODIFICATION is set to FALSE (the default value) in the web.xml file.

Disable checking for CSS file modifications.

The org.apache.myfaces.trinidad.CHECK_FILE_MODIFICATION parameter controls when CSS file modification checks are made. To aid in performance, this configuration option defaults to false - do not check for css file modifications. Set this to TRUE if you want the skinning css file changes to be reflected without stopping or starting the server.

Enable content compression.

By default, style classes that are rendered are compressed to reduce page size. In production environments, make sure you remove the DISABLE_CONTENT_COMPRESSION parameter from the web.xml file or set it to FALSE.

For debugging, turn off the style class content compression. You can do this by setting the DISABLE_CONTENT_COMPRESSION property to TRUE.

Enable JavaScript obfuscation.

ADF Faces supports a runtime option for providing a non-obfuscated version of the JavaScript library. The obfuscated version is supplied by default, but the non-obfuscated version is supplied for development use. Obfuscation reduces the overall size of the JavaScript library by about 50%.

To provide an obfuscated ADF Faces build, set the org.apache.myfaces.trinidad.DEBUG_JAVASCRIPT parameter to FALSE in the web.xml file.

Enable library partitioning.

In the Oracle 11g Release, library partitioning is on by default. In previous versions library partitioning was off by default. Ensure that the library partitioning is on by validating the oracle.adf.view.rich.libraryPartitioning.DISABLED property is set to false in the web.xml file.


8.2.3 Tuning ADF Faces Component Attributes

Table 8-3 provides configuration recommendations for ADF Faces Component Attributes:

Table 8-3 ADF Faces Component Attributes

Configuration Recommendation Description

Use the childCreation property for panelTabbed components to control when the contents of the ShowDetailItem children are created.

By default, the child components of showDetailItems inside a panelTabbed are created even if they are not disclosed. This can cause unnecessary memory and CPU usage.

To control when the contents of the showDetailItems children are created, use the childCreation property. Using this property can improve server-side performance by postponing construction of the components until they are likely to be disclosed.

The childCreationproperty options are:

  • immediate

    All showDetailItem children will be populated immediately

  • lazy

    showDetailItem children will be populated when they are likely to be disclosed and kept in memory thereafter

  • lazyuncached

    showDetailItem children will be populated when they are likely to be disclosed and may be removed when undisclosed

Use the immediate data delivery attribute with ADF Rich Client components.

ADF Rich Client components have an immediate attribute. If a component has its immediate attribute set to TRUE (immediate="true"), then the validation, conversion, and events associated with the component are processed during the applyRequestValues phase. These are some cases where setting immediate to TRUE can lead to better performance.

  • The commandNavigationItem in the navigationPane can use the immediate attribute set to TRUE to avoid processing the data from the current screen while navigating to the new page.

  • If the input component value has to be validated before the other values, immediate should be set to TRUE. In case of an error it be detected earlier in the cycle and additional processing be avoided.

ADF Rich Client is built on top of JSF and uses standard JSF lifecycle. See "Understanding the JSF and ADF Faces Lifecycles" in Oracle Fusion Middleware Web User Interface Developer's Guide for Oracle Application Development Framework.

There are some important issues associated with the immediate attribute. Refer to "Using the Immediate Attribute" in Oracle Fusion Middleware Web User Interface Developer's Guide for Oracle Application Development Framework for more information.

Note that this is an advanced feature. Most of the performance improvements can be achieved using the af:subform component. Refer to Oracle Fusion Middleware Web User Interface Developer's Guide for Oracle Application Development Framework for af:subform details.

Use the "visible" and "rendered" attributes.

All ADF Faces Rich Client display components have two properties that dictate how the component is displayed on the page:

  • The visible property specifies simply whether the component is to be displayed on the page, or is to be hidden.

  • The rendered property specifies whether the component shall exist in the client page at all.

The EL expression is commonly used to control these properties. For better performance, consider setting the component to "not rendered" instead of "not visible", assuming there is no client interaction with the component. Making a component "not rendered" can improve server performance and client response time since the component does not have client side representation.

Use client-side events.

ADF Rich Client framework provides the client-side event model based on component-level events rather than DOM level. The client-side event model is a very useful feature that can speed up the application. Review the following performance considerations:

  • Consider using client-side events for relatively simple event handling that can be done on the client side. This improves client side performance by reducing the number of server round trips. Also, it can increase server-side throughput and scalability since requests do not have to be handled by the server.

  • By default, the events generated on the client by the client components are propagated to the server. If a client-side event handler is provided, consider canceling the event at the end of processing so that the event does not propagate to the server.

Limit character length when using "id" attribute.

The "id" attribute should not be longer than 7 characters in length. This is particularly important for naming containers. A long id can impact performance as the amount of HTML that must be sent down to the client is impacted by the length of the ids.

Use client-side components.

ADF Rich Client framework has client-side components that play a role in client-side event handling and component behavior. The clientComponent attribute is used to configure when (or if) a client-side component should be generated. Setting clientComponent attribute to TRUE has a performance impact, so determine if its necessary to generate client-side components.

For more information, see "Client-side Components" in Oracle Fusion Middleware Web User Interface Developer's Guide for Oracle Application Development Framework.

Optimize popups by setting the childCreation attribute on af:popup to deferred for a server-side performance enhancement

Setting childCreation to deferred postpones construction of the components under the popup until the content is delivered. A deferred setting can therefore reduce the footprint of server-side state in some cases.

CAUTION: This approach CANNOT be used if any of the following tags are present inside the popup:

  • f:attribute

  • af:setPropertyListener

  • af:clientListener

  • af:serverListener

It also CANNOT be used if you need to refer to any child components of the popup before the popup is displayed. Setting childCreation="deferred" will postpone creating any child components of the popup and you cannot refer to them until after the popup is shown.

Use the lazy data delivery attribute to optimize popups that include regions.

If setting the childCreation attribute to deferred cannot be used, or you have regions within the popup, consider using the lazy data delivery attribute to optimize the popup.

For this scenario, perform the following:

  1. Edit the pageDef for the page or fragment containing the region in the popup.

  2. Locate the <taskflow> binding entry for the task flow in question.

  3. Set the activation attribute to conditional (this is one of the options from the pull down list in the property inspector).

  4. Set the active attribute to an EL expression that initially resolves to a boolean false.

  5. In a popupFetch setPropertyListener, update the underlying value tested by the EL used in Step 4 so that it resolves to true.


8.2.4 Tuning Table and Tree Components

Table, Tree, and TreeTable are some of the most complex, and frequently used, components. Since these components can include large sets of data, they can be the common source of performance problems. Table 8-4 provides some performance recommendations.

Table 8-4 Table and Tree Component Configurations

Configuration Recommendation Description

Use editingMode="clickToEdit".

When using editingMode="editAll" all content of the editable values holders and their client components is sent. This can significantly increase the HTTP payload and the Document Object Model (DOM) content on the client.

Consider switching to editingMode="clickToEdit" to reduce the amount of transmitted data and potentially improve user interaction.

Set the RowCountTreshold to optimize the SELECT COUNT execution for ADF table rendering.

By default table components render in "known row count" mode which means it will size scrollbar based on total number of rows. This mode provides rich UI, but also requires SELECT COUNT execution for ADF table rendering to get total the number of rows. In some cases SELECT COUNT can be slow and hard to optimize on the database.

If ADF-Business Components (BC) is used, then RowCountTreshold can be set to -1 which will avoid SELECT COUNT but the table will render in "unknown row count" mode.

The other option is to set RowCountTreshold to positive N which causes an optimized SELECT COUNT to execute and the table will have a richer rendering as long as user scrolls within N rows.

Reduce fetchSize when possible.

A larger fetch size attribute on af:table implies that more data needs to be processed, fetched from the server, and displayed on the client. This can also increase the amount of DOM displayed on the client.

Modify table fetch size.

Tables have a fetch size which defines the number of rows to be sent to the client in one round-trip. To get the best performance, keep this number low while still allowing enough rows to fulfill the initial table view port. This ensures the best performance while eliminating extra server requests.

In addition, consider keeping the table fetch size and iterator range size in sync. By default, the table fetch size is set to the EL expression #{bindings.<name>.rangeSize} and should be equal to the iterator size.

For more information see "Using Tables and Trees" in Oracle Fusion Middleware Web User Interface Developer's Guide for Oracle Application Development Framework.

Disable column stretching.

Columns in the table and treeTable components can be stretched so that there is no unused space between the end of the last column and the edge of the table or treeTable component. This feature is turned off by default due to potential performance impacts. Turning this feature on may have a performance impact on the client rendering time, so use caution when enabling this feature with complex tables.

Use header rows and frozen columns only when necessary.

The table component provides features that enable you to set the row Header and frozen columns. These options can provide a well-designed interface which can lead to a good user experience. However, they can impact client-side performance. To get the best performance for table components, use these options only when they are needed.

Disable popups that cannot be displayed by the user.

Most cells have no attachments initially and only one popup can be displayed by the user. Therefore, popups that cannot be displayed by the user should have renderer="false". This will cut down the unnecessary DOM/client components sent to the browser. Similarly the DOM has a panelGroupLayout with a number of cells which are empty. There is no need to send DOM for empty cells.


8.2.4.1 Specifying a Data Delivery Method

Data for Table, Tree, and other stamped components can be delivered immediately or lazily. The table below describes tuning scenarios when one option is better for performance than the other. In many cases you must consider what is being tuned to determine which option to use.

By default, lazy delivery is used. This means that data is not delivered in the initial response from the server. Rather, after the initial page is rendered, the client asks the server for the data and gets it as a response to the second request.

In the case of immediate delivery, data can be in line with the response to the page request. It is important to note that data delivery is per component and not per page. This means that these two can be mixed on the same page.

When choosing between these two options, consider the following:

Lazy Delivery (default)

Lazy delivery should be used for tables, or other stamped components, which are known to have slow fetch time. The examples are stamped components are the ones based on data controls using web services calls or other data controls with slow data fetch. Lazy delivery can also be used on pages where content is not immediately visible unless the user scrolls down to it. In this case the time to deliver the visible context to the client will be shorter, and the user perceives better performance.

Lazy delivery is implemented using data streaming technique. The advantage of this approach is that the server has the ability to execute data fetches in parallel and stream data back to the client as soon as the data is available. The technique performs very well for a page with two tables, one that returns data very quickly and one that returns data very slowly. Users see the data for the fast table as soon as the data is available.

NOTE: When using lazy delivery, consider using whenAvailable to first determine if the data is available, then render if it is not available.

Executing data fetches in parallel also speeds up the total time to fetch data. This gives an advantage to lazy loading in cases of multiple, and possibly slow, data fetches. While streaming is the default mechanisms to deliver data in lazy mode, parallel execution of data controls is not. In order to enable parallel execution, open the page definition and change RenderHint on the iterator to background.

In certain situations, the advantage of parallel execution is faster response time. Parallel execution could potentially use more resources due to multiple threads executing request in parallel and possibly more database connections will be opened.

Consider using parallel execution only when there are multiple slow components on the page and the stamped components belong to different data control frames (such as isolated taskflows). Since parallel execution synchronizes on the data control frame level, when there is a single data control frame parallel execution may not improve performance.

Immediate Delivery

Immediate delivery (contentDelivery="immediate") should be used if table data control is fast, or if it returns a small set of data. In these cases the response time be faster than using lazy delivery.

Another advantage of immediate delivery is less server resource usage, compared to lazy delivery. Immediate delivery sends only one request to the server, which results in lower CPU and memory usage on the server for the given user interaction.

There are some important issues associated with the immediate attribute. Refer to "Using the Immediate Attribute" in Oracle Fusion Middleware Web User Interface Developer's Guide for Oracle Application Development Framework for more information.


8.2.4.2 Performance Considerations for autoSuggest

autoSuggest is a feature that can be enabled for inputText, inputListOfValues, and inputComboboxListOfValues components. When the user types characters in the input field, the component displays a list of suggested items. The feature performs a query in the database table to filter the results. In order to speed up database processing, a database index should be created on the column for which autosuggest is enabled. This improves the component's response times especially when the database table has a large number of rows.

Note:

In order to prevent large number of autoSuggest items being returned, consider using the maxSuggestedItems property on autoSuggestBehavior with a value appropriate for your usage.

8.2.5 Tuning Data Visualization Tool (DVT) Components

Data Visualization Tool (DVT) components are built on top of ADF Rich Client components. DVT components include graphs, gauges, Gantt charts, pivot tables and maps. Table 8-5 provides some configuration recommendations for DVT components:

Table 8-5 DVT Component Configurations

Configuration Recommendation Description

Modify the RangeSize attribute.

The RangeSize attribute defines the number of rows to return simultaneously. A RangeSize value of -1 causes the iterator to return all the rows. Using a lower value may improve performance, but it may be harder to manage the data. Also, any data beyond rangeSize will not be available in the view.

Use horizontal text instead of vertical text.

By default, pivot tables use horizontal text for column headers. However, there is an option to use vertical text as well. Vertical text can be used by specifying a CSS style for the header format such as:

writing-mode:tb-rl;filter:flipV flipH;

While vertical text can look better in some cases, it has a performance impact when the Firefox browser is used.

The problem is that vertical text is not native to Firefox as it is in Internet Explorer. To show vertical text, the pivot table uses images produced by GaugeServlet. These images cannot be cached as the text is dynamic and depends on the binding value. Due to this, every rendering of the pivot table incurs extra round-trips to the server to fetch the images, which impact network traffic, server memory, and CPU.

To have the best performance, consider using horizontal text instead of vertical text.

Avoid using dynamic resizing.

The dynamicResize="DYNAMIC_SIZE" property on DVT graph and gauge provides the ability to size a component based on available area on the browser. Since the available area is not always known before geometry management calculates it, a second request is needed to fetch the correct graph or gauge size.

The additional fetch can impact performance. If possible, set the dynamic resize property on the component and avoid using dynamic resize and explicity set the correct area size.

Use HTML5, instead of Flash, as the default image format.

As of Oracle Fusion Middleware 11g Release 1 (11.1.1.7.0), graph and gauge supports HTML5 output format. A new web.xml context parameter has been introduced to change the default output format to HTML5. The context parameter, oracle.adf.view.rich.dvt.DEFAULT_IMAGE_FORMAT, will be automatically added to new applications.

Applications that have this context parameter, but have not yet specified an image format, will automatically default to HTML5. Valid values are HTML5 and FLASH. For the applications that do not have this context parameter, the default rendering for Graph and Gauge would be Flash.

To maintain optimal performance, use HTML5 for all modern browsers.


8.3 Advanced Tuning Considerations

After you have performed the tuning modifications recommended in the previous section, you can make additional changes that are specific to your ADF Server deployment. Consider carefully whether the recommendations in this section are appropriate for your environment.

8.3.1 Tuning ADF Server Performance

Oracle ADF Server components consist of the non-UI components within ADF. These include the ADF implementations of the model layer (ADFm), business services layer (ADFbc), and controller layer (ADFc). As the server components are highly configurable, it is important to choose the combination of configurations that best suits the available resources with the specified application performance and functionality.

8.3.1.1 HTTP Session Timeout Tuning

For ADF applications with a significant user community, the amount of memory held by sessions waiting to expire can negatively impact performance when the default HTTP session timeout of 45 minutes is used. The memory being held can be higher than what is physically available, causing the server to not be able to handle the load. For large numbers of users, such as those using a public facing website, the session timeout should be as short as possible.

To improve performance, consider modifying the default session timeout value (in minutes) in the web.xml file. Use a session timeout value that works with your use case scenario. The example below shows a session timeout of 10 minutes:

<session-config>
 <session-timeout>
 10
 </session-timeout>
</session-config>

8.3.1.2 View Objects Tuning

View objects (VOs) provide many tuning options to enable a developer to tailor the View Object to the application's specific needs. View Objects should be configured to use the minimal feature set required to fulfill the functional requirement. The Oracle Fusion Middleware Fusion Developer's Guide for Oracle Application Development Framework provides detailed information on tuning View Objects. The following sections provide some tips pertaining to View Object performance.

8.3.1.2.1 Creating View Objects

To maximize View Object performance, the View Object should match the intended usage. For instance, data retrieved for a list of values pick-list is typically read-only, so a read-only View Object should be used to query this data. Tailoring the View Object to the specific needs of the application can improve performance, memory usage, CPU usage, and network usage.

View Object Type Description

Read-only View Objects

Consider using a read-only View Object if the View Object does not have to insert or update data. There are two options for read-only View Objects:

  • Non-updatable EO-based View Objects

  • Expert-mode View Objects

Non-updatable EO-based View Objects offer the advantage of a customizable select list at runtime which retrieve attributes needed in the UI, data reads from local cache (instead of re-executing a database query), and data consistency with other updatable View Objects based on the same EO.

Expert-mode View Objects have the ability to perform SQL operations not supported by EOs and avoid the small performance impact from coordinating View Object and EO rows. EO-based View Objects can be marked non-updatable by deselecting the "updatable" option in the selected EO for the View Object, which can also be done by adding the parameter ReadOnly="true" on the EntityUsage attribute in the View Object XML definition.

Insert-only View Objects

For View Objects that are used only for inserting records, you can prevent unnecessary select queries from being executed when using the View Object. To do this, set the option No Rows in the Retrieve from the Database group box in the View Objects Overview tab. This sets MaxFetchSize to 0 (zero) for the View Object definition.

Runtime-created View Objects

View Objects can be created at runtime using the createViewObjectFromQueryStmt() API on the AM. However, avoid using runtime-created View Objects unless absolutely necessary due to potential performance impacts and complexity of tuning.


8.3.1.2.2 Configuring View Object Data Fetching

View Object performance is largely dependent on how the view object is configured to fetch data. If the fetch options are not tuned correctly for the application, then the view object may fetch an excessive amount of data or may take too many round-trips to the database. Fetch options can be configured through the Retrieve from the Database group box in the View Object dialog Figure 8-1.

Figure 8-1 View Object Dialog

Description of Figure 8-1 follows
Description of "Figure 8-1 View Object Dialog"

Fetch Option Description

Fetch Mode

The default fetch option is the All Rows option, which is retrieved as needed (FetchMode="FETCH_AS_NEEDED") or all at once (FetchMode="FETCH_ALL"), depending on which option is appropriate. The FETCH_AS_NEEDED option ensures that an executeQuery() operation on the view object initially retrieves only as many rows as necessary to fill the first page of a display. The number of rows is set based on the view object's range size.

CAUTION: Avoid using the FetchMode="FETCH_ALL" unless required. This option can impact performance.

Fetch Size

In conjunction with the fetch mode option, the Batches field controls the number of records fetched simultaneously from the database (FetchSize in the View Object, XML). The default value is 1, which may impact performance unless only 1 row is fetched. The suggested configuration is to set this value to n+1 where n is the number of rows to be displayed in the user interface.

Note that for DVT objects, Fetch Size should be n+1 where n is either rangeSize or the likely maximum rowset size if rangeSize is -1.

Max Fetch Size

The default max fetch size for a View Object is -1, which means that there is no limit to the number of rows the View Object can fetch. Setting a max fetch size of 0 (zero) makes the View Object insert-only. In cases where the result set should only contain n rows of data, the option Only Up to Row Number should be selected and set or call setMaxFetchSize(N) to set this programmatically. To set this manually, add the parameter MaxFetchSize to the View Object XML.

For View Objects whose WHERE clause expects to retrieve a single row, set the option At Most One Row. This option ensures that the view object knows not to expect any more rows and skips its normal test for that situation. In this case no select query is issued and no rows are fetched.

Max fetch size can also be used to limit the impact from an non-selective query that may return hundreds (or thousands) of rows. In such cases, specifying the max fetch size limits the number of rows that can be fetched and stored into memory.

Forward-Only Mode

If a data set is only traversed going forward, then forward-only mode can help performance when iterating through the data set. This can be configured by programmatically calling setForwardOnly(true) on the View Object. Setting forward-only can also prevent caching previous sets of rows as the data set is traversed.


8.3.1.2.3 Additional View Object Configurations

Table 8-6 provides additional tuning considerations when using the View Object:

Table 8-6 Additional View Object Configurations

Configuration Recommendation Description

Optimize large data sets.

View Objects provide a mechanism to page through large data sets so that a user can jump to a specific page in the results. This is configured by calling setRangeSize(N) followed by setAccessMode(RowSet.RANGE_PAGING) on the View Object where N is the number of rows contained within 1 page. When navigating to a specific page in the data set, the application can call scrollToRangePage(P) on the View Object to navigate to page P. Range paging fetches and caches only the current page of rows in the View Object row cache at the cost of another query execution to retrieve each page of data. Range paging is not appropriate where it is beneficial to have all fetched rows in the View Object row cache (for example, when the application must read all rows in a data set for an LOV or page back and forth in records of a small data set).

Get an estimated row count using getEstimatedRowCount.

Use getEstimatedRowCount instead of getRowCount to prevent any impacts to performance. getRowCount can impact performance because it fetches all rows to memory and then count them.

Disable "spillover" configurations when possible.

You can use the data source as "virtual memory" when the JVM container runs out of memory. By default this is disabled and can be enabled (if needed) by setting jbo.use.pers.coll=true. Keep this option disabled (if possible) to avoid a potential performance impact.

Review SQL style configuration.

If the generic SQL92 SQL style is used to connect to generic SQL92-compliant database, then some View Object tuning options do not apply. The View Object fetch size is one such tuning option. When SQL92 SQL style is used, the fetch size defaults to 10 rows, regardless of what is configured for the View Object. The SQL style is set when defining the database connection. By default when defining an Oracle database connection, the SQL style can be Oracle. To manually override the SQL style, pass the parameter -Djbo.SQLBuilder="SQL92" to the JVM at startup.

Use bind variables for view object queries.

If the query associated with the View Object contains values that may change from execution to execution, consider using bind variables. This may help to avoid re-parsing the query on the database. Bind variables can be added to the View Object in the Query section of the View Object definition.

Remove unused list bindings to improve performance.

Use query optimizer hints for view object queries.

The View Object can pass hints to the database to influence which execution plan to use for the associated query. The optimizer hints can be specified in the Retrieve from the Database group box.

CAUTION: To prevent performance issues, do not use ENDSWITH/CONTAINS on required/selectively required view criteria items.

Use dynamic SQL generation.

View Objects can be configured to dynamically generate SQL statements at runtime instead of defining the SQL at design time. A View Object instance, configured with generating SQL statements dynamically, can avoid re-querying a database. This is especially true during page navigation if a subset of all attributes with the same key Entity Object list is used in the subsequent page navigation. Performance can be improved by activating a superset of all the required attributes to eliminate a subsequent query execution.

Passivate transient expressions.

Consider passivating TransientExpressions to maintain performance. This is controlled by a flag on EO/VO level or individual expression level. From the View Object dialog screen, select Including All Transient Values when enabling Passivate.


8.3.1.3 Batch Processing

Batch processing enables multiple inserts, updates, and deletes to be processed together when sending the operations to the database. Enabling this feature is done on the Entity Object (EO) by either selecting the "Use Update Batching" check box in the Tuning section of the EO's General tab, or by directly modifying the EO's XML file and adding the parameter BatchThreshold with the specified batch size to the Entity attribute.

The BatchThreshold value is the threshold at which a group of operations can be batched instead of performing each operation one at a time. If the threshold is not exceeded, then rows may be affected one at a time. On the other hand, more rows than specified by the threshold can be batched into a single batch.

Note that the BatchThreshold configuration for the EO is not compatible if an attribute in the EO exists with the configuration to refresh after insert (RetrievedOnInsert="true") or update (RetrievedOnUpdate="true").

8.3.1.4 RangeSize Tuning

This parameter controls the number of records ADFm requests from the BC layer simultaneously. The default RangeSize is 25 records. Consider setting this value to the number of records to be displayed in the UI simultaneously for the View Object so that the number of round-trips between the model and BC layers is reduced to one. This is configured in the Iterator attribute of the corresponding page's page definition XML.

8.3.1.5 Application Module Design Considerations

Designing an application's module granularity is an important consideration that can significantly impact performance and scalability. It is important to note that each root application module generally holds its own database connection. If a user session consumes multiple root application modules, then that user session can potentially hold multiple database connections simultaneously. This can occur even if the connections are not actively being used, due to the general affinity maintained between an application module and a user session. To reduce the possibility that a user can hold multiple connections at once, consider the following options:

  • Design larger application modules to encompass all of the functionality that a user needs.

  • Nest smaller application modules under a single root application module so that the same database connection can be shared among the nested application modules.

  • Use lazy loading for application modules. In the Application Module tuning section, customize runtime instantiation behavior to use lazy loading. Lazy loading can also be set JVM-wide by adding the following JVM argument:

    -Djbo.load.components.lazily=true
    

8.3.1.6 Application Module Pooling

Application module (AM) pooling enables multiple users to share several application module instances. The configurations for the AM pool vary depending on the expected usage of the application.

Most of the AM pool parameters can be set through Oracle JDeveloper. The configurations are saved in bc4j.xcfg, which can be manually edited if needed. Parameters can also be set at the system level by specifying these as JVM parameters (-Dproperty=value). The bc4j.xcfg configuration takes precedence over the JVM configuration; this enables a generic system-level configuration to be overridden by an application-specific exception.

Table 8-7 Application Module (AM) Pool Tuning

Configuration Recommendation Description

Use the lazy data delivery method.

By default AM loads all the associated definitions when the instance of AM is created. AM can have a large number of VOs associated with it. This can make loading of AM slower and passivation slower.

To prevent possible performance issues, set LoadComponentsLazily="true".

Optimize the number of AM pools in the application.

Parameters applied at the system level are applied per AM pool. If the application uses more than 1 AM pool, then system-level values for the number of AM instances must be multiplied by the number of AM pools to realize the actual limits specified on the system as a whole.

For example, if an application uses 4 separate AM pools to service the application, and a system-level configuration is used to limit the max AM pool size to 100, then this can result in a maximum of 400 AM instances (4 pools * 100 max pool size).

If the intent is to limit the entire application to a max pool size of 100, then the system-level configuration should specify a max pool size of 25 (100 max pool size / 4 pools). Finer granularity for configuring each AM pool can be achieved by configuring each pool separately through JDev or directly in bc4j.xcfg.

Optimize the number of database connections.

By default AM instances retain their database connections even when checked back into the AM pool. There are many performance benefits to maintain this association. To maintain performance, consider configuring more AM instances than the maximum number of specified database connections.

NOTE: If you have an AM pool that needs to be used as root pool, consider tuning at the specific AM pool level. For pools that are infrequently used, consider tuning pool sizes on the pool level so that top-level application parameters are not used.


8.3.1.6.1 General AM Pool Configurations

The following guidelines can be used as a general starting point when tuning AM and AM pool behavior. More specific tuning for memory or CPU usage can be found in .

Table 8-8 AM Pool Tuning Parameters

Parameter Description

Initial Pool Size

jbo.ampool.initpoolsize

Specifies the number of application module instances to create when the pool is initialized (default is zero). Setting a nonzero initial pool size increases the time to initialize the application, but improves subsequent performance for operations requiring an AM instance.

Configure this value to 10% more than the anticipated number of concurrent AM instances required to service all users.

Maximum Pool Size

jbo.ampool.maxpoolsize

Specifies the maximum number of application module instances that the pool can allocate (default is 4096). The pool can never create more application module instances than this limit imposes. A general guideline is to configure this to 20% more than the initial pool size to allow for some additional growth.

Minimum Available Size

jbo.ampool.minavailablesize

The minimum number of available application module instances that the pool monitor should leave in the pool during a resource cleanup operation, when the server is under light load.

Set to 0 (zero) if you want the pool to shrink to contain no instances when all instances have been idle for longer than the idle time-out after a resource cleanup.

The default is 5 instances.

While application module pool tuning allows different values for the jbo.ampool.minavailablesize | jbo.ampool.maxavailablesize parameters, in most cases it is fine to set these minimum and maximum tuning properties to the same value.

Maximum Available Size

jbo.ampool.maxavailablesize

The ideal maximum number of available application module instances in the pool when the server is under load.

When the pool monitor wakes up to do resource cleanup, it will try to remove available application module instances to bring the total number of available instances down to this ideal maximum. Instances that have been not been used for a period longer than the idle instance time-out will always get cleaned up at this time, then additional available instances will be removed if necessary to bring the number of available instances down to this size.

The default maximum available size is 25 instances. Configure this to leave the maximum number of available instances desired after a resource cleanup. A lower value generally results in more application module instances being removed from the pool on a cleanup.

While application module pool tuning allows different values for the jbo.ampool.maxavailablesize | jbo.ampool.minavailablesize parameters, in most cases it is fine to set these minimum and maximum tuning properties to the same value.

Referenced Pool Size

jbo.recyclethreshold

Specifies the maximum number of application module instances in the pool that attempt to preserve session affinity for the next request made by the session that used them last before releasing them to the pool in managed-state mode (default is 10).

The referenced pool size should always be less than or equal to the maximum pool size. This enables the configured number of available instances to try and remain "loyal" to the affinity they have with the most recent session that released them in managed state mode.

Configure this value to the expected number of concurrent users that perform multiple operations with short think times. If there are no users expected to use the application with short think times, then this can be configured to 0 (zero) to eliminate affinity.

Maximum Instance Time to Live

jbo.ampool.timetolive

The number of milliseconds after which to consider an connection instance in the pool as a candidate for removal during the next resource cleanup regardless of whether it would bring the number of instances in the pool below minavailablesize.

The default is 3600000 milliseconds of total time to live (which is 3600 seconds, or one hour). A lower value reduces the time an application module instance can exist before it must be removed at the next resource cleanup. The default value is sufficient for most applications. A higher value increases the time an application module instance can exist before it must be removed at the next cleanup.

Idle Instance Timeout

jbo.ampool.maxinactiveage

The number of milliseconds after which to consider an inactive application module instance in the pool as a candidate for removal during the next resource cleanup.

The default is 600000 milliseconds of idle time (which is 600 seconds, or ten minutes). A lower value results in more application module instances being marked as a candidate for removal at the next resource cleanup. A higher value results in fewer application module instances being marked as a candidate for removal at the next resource cleanup.

Pool Polling Interval

jbo.ampool.monitorsleepinterval

The length of time in milliseconds between pool resource cleanup.

While the number of application module instances in the pool will never exceed the maximum pool size, available instances which are candidates for getting removed from the pool do not get "cleaned up" until the next time the application module pool monitor wakes up to do its job.

The default is to have the application module pool monitor wake up every 600000 milliseconds (which is 600 seconds, or ten minutes). Configuring a lower interval results in inactive application module instances being removed more frequently to save memory. Configuring a higher interval results in less frequent resource cleanups.

Failover

jbo.dofailover

Specifies whether to disable or enable failover. By default, failover is disabled. To enable failover, set the parameter to true.

NOTE: When enabling application module state passivation, a failure can occur when Oracle WebLogic Server is configured to forcibly release connection back into the pool. A failure of this type produces a SQLException (Connection has already been closed) that is saved to the server log. The exception is not reported through the user interface.

To ensure that state passivation occurs and changes are saved, set an appropriate value for the weblogic-application.xml deployment descriptor parameter inactive-connection-timeout-seconds on the <connection-check-params> pool-params element.

Setting the deployment descriptor parameter to several minutes, in most cases, should avoid forcing the inactive connection timeout and the resulting passivation failure. Adjust the setting as needed for your environment.

Locking Mode

jbo.locking.mode

Specifies the locking mode (optimistic or pessimistic). The default is pessimistic, which means that a pending transaction state can be created on the database with row-level locks. With pessimistic locking mode, each time an AM is recycled, a rollback is issued in the JDBC connection. Web applications should set the locking mode to optimistic to avoid creating the row-level locks.

Database Connection Pooling

jbo.doconnectionpooling

Specifies whether the AM instance can be disconnected from the database connection when the AM instance is returned to the AM pool. This enables an application to size the AM pool larger than the database connection pool. The default is false, which means that an AM instance can retain its database connection when the AM instance is returned to the AM pool. When set to true, the AM can release the database connection back to the database connection pool when the AM instance is returned to the AM pool. Note that before an AM is disconnected from the database connection, a rollback can be issued on that database connection to revert any pending database state.

Transaction Disconnect Level

jbo.txn.disconnect_level

When used in conjunction with jbo.doconnectionpooling=true, specifies BC4J behavior for maintaining JDBC ResultSets. By default jbo.txn.disconnect_level is 0, and passivation can be used to close any open ResultSets when the database connection is disconnected from the AM instance. Configuring jbo.txn.disconnect_level to 1 can prevent this behavior to avoid the passivation costs for this situation.


For parameters that can be configured for memory-constrained systems, see Table 8-9.

Table 8-9 AM Pool Sizing Configurations - Memory Considerations

Parameter Description

Initial Pool Size

jbo.ampool.initpoolsize

Set this to a low value to conserve memory at the cost of slower performance when additional AM instances are required. The default value of 0 (zero) does not create any AM instances when the AM pool is initialized.

Maximum Pool Size

jbo.ampool.maxpoolsize

Configure this to prevent the number of AM instance from exceeding the determined value. However, if this is set too low, then some users may see an error accessing the application if no AM instances are available.

Minimum Available Pool Size

jbo.ampool.minavailablesize

Set to 0 (zero) to shrink the pool to contain no instances when all instances have been idle for longer than the idle time out after a resource cleanup. However, a setting of 1 is commonly used to avoid the costs of re-creating the AM pool.

Maximum Available Pool Size

jbo.ampool.maxavailablesize

Configure this to leave the maximum number of available instances specified after a resource cleanup.


For parameters that can be configured to reduce the load on the CPU to some extent through a few parameters, see Table 8-10.

Table 8-10 AM Pool Sizing Configurations - CPU Considerations

Parameter Description

Initial Pool Size

jbo.ampool.initpoolsize

Set this value to the number of AM instances you want the application pool to start with. Creating AM instances during initialization takes the CPU processing costs of creating AM instances during the initialization instead of on-demand when additional AM instances are required.

Session Recycle Threshold jbo.recyclethreshold

Configure this value to maintain the AM instance's affinity to a user's session. Maintaining this affinity as much as possible save the CPU processing cost of needing to switch an AM instance from one user session to another.


8.3.1.6.2 AM Pool Resource Cleanup Configurations

These parameters affect the frequency and characteristics for AM pool resource cleanups.

For memory-constrained systems, configure the AM pool to clean up more AM instances more frequently so that the memory consumed by the AM instance can be freed for other purposes.

The AM pool can be configured to reduce the need for CPU processing by allowing more AM instances to exist in the pool for longer periods of time. This generally comes at the cost of consuming more memory.

CAUTION: Reducing the number of available AM instances and increasing the frequency of cleanups can result in higher CPU usage and longer response times.

Table 8-11 AM Pool Resource Cleanup Configurations - Memory Considerations

Parameter Description

Minimum Available Size jbo.ampool.minavailablesize

A setting of 0 (zero) shrinks the pool to contain no instances when all instances have been idle for longer than the idle time out. However, a setting of 1 is commonly used to avoid the costs of re-creating the AM pool

Maximum Available Size

jbo.ampool.maxavailablesize

A lower value generally results in more AM instances being removed from the pool on a cleanup.

Setting these to a higher value leaves more idle instances in the pool, so that AM instances do not have to be recreated at a later time. However, the values should not be set excessively high to keep more AM instances than can be required at maximum load.

Time to Live

jbo.ampool.timetolive

A lower value reduces the time an AM instance can exist before it must be removed at the next resource cleanup.

A higher value increases the time an AM instance can exist before it must be removed at the next resource cleanup.

CAUTION: A setting of -1 implies unlimited time to live. This setting should only be used for well tested applications with no memory leaks.

Maximum Inactive Age

jbo.ampool.maxinactiveage

A low value results in more AM instances being marked as a candidate for removal at the next resource cleanup.

A higher value results in fewer AM instances being marked as a candidate for removal at the next resource cleanup.

Monitor Sleep Interval

jbo.ampool.monitorsleepinterval

This controls how frequent resource cleanups can be triggered. Configuring a lower interval results in inactive AM instances being removed more frequently to save memory.

Configuring a higher interval results in less frequent resource cleanups.


8.3.1.7 ADFc: Region Usage

Table 8-12 ADFc Region Configurations

Configuration Recommendation Description

Add regions to a page only when the specific functionality is required.

Adding regions to a page can be a powerful addition to the application. However, regions can be a resource-intensive component on the page. For better performance, consider using regions only when the specific functionality is required.

Disable detect-metadata-changes in adf-config.

Disable detect-metadata-changes by setting it to false in adf-config.

Detecting metadata changes is only needed for applications that are not using ADFc DT@RT operations to customize unbounded task flows. If the application does customize unbounded flow, the property can be enabled and disabled as needed using RT API's.

Consider nesting "hidden" popups inside of the 1 "visual" root component when possible.

Regions with multiple root components can have a negative impact on performance. Even if only 1 "visual" root component exists, and the rest are "hidden" popups, there may still be an impact to performance.

For example, if you do not want stretching, consider wrapping everything in a panelGroupLayout layout="vertical" or "scroll" (as applicable). If you do want stretching, consider putting the "visual" root in the "center" facet and then put the popups in the "bottom" facet and set bottomHeight="0px" on the panelStretchLayout.


8.3.1.8 Defer Task Flow Execution

By default, task flows are activated when the page is loaded, even when the task flow is not initially rendered. This causes unnecessary overhead if the task flow is never displayed.

8.3.1.9 Configuring the Task Flow Inside Switcher

By default, task flows under switchers are activated when the page is loaded, not when the switcher facet is displayed. To avoid this, use conditional activation and set "active" to an expression language (EL) expression that returns 'true' when the facet is displayed. Consider using the same condition for switcher to drive task flow conditional activation.

Example of switcher:

<af:switcher id="s1" defaultFacet="1" facetName="#{pageFlowScope.facet}">
            <f:facet name="1">
                <af:region value="#{bindings.TF1.regionModel}" id="r1"/> 
            </f:facet> 
            <f:facet name="2">
                <af:region value="#{bindings.TF2.regionModel}" id="r2"/> 
            </f:facet> 
 </af:switcher>
 

Associated binding:

<taskFlow id="tTF1" taskFlowId="-----" active="#{pageFlowScope.facet=='1'}" activation="conditional" xmlns="http://example.host.com/adf/controller/binding"/> 
<taskFlow id="tTF2" taskFlowId="-----" active="#{pageFlowScope.facet=='2'}" activation="conditional" xmlns="http://example.host.com/adf/controller/binding"/> 

8.3.1.10 Reusing Static Data

If the application contains static data that can be reused across the application, the cache data can be collected using a shared application module. More information on creating and using shared application modules can be found in "Sharing Application Module View Instances" in Oracle Fusion Middleware Fusion Developer's Guide for Oracle Application Development Framework.

8.3.1.11 Conditional Validations

For resource-intensive validations on entity attributes, consider using preconditions to selectively apply the validations only when needed. The cost of validation must be weighted against the cost of the precondition to determine if the precondition is beneficial to the performance. More information on specifying preconditions for validation can be found in "How to Set Preconditions for Validation" in Oracle Fusion Middleware Fusion Developer's Guide for Oracle Application Development Framework.

8.3.2 Tuning Groovy Usage

If you have applications that are using Groovy to evaluate expressions, then you may need to tune the expressions to improve performance. Groovy script parsing can impact performance, so its best to use it only when required.

For example, if you are using groovy to evaluate a common expression like this:

Date currentDate = null; 
    .......
        ExprEval expression = new ExprEval("adf.currentDate", ExprEval.EXPR_STYLE_GROOVY); 
        currentDate = (Date)expression.evaluate(null); 

You might improve performance by making the following changes:

  • If date and time are important, you might improve performance by using the following:

    currentDate = new Date(System.currentTimeMillis()); 
    
  • If the current time is not required, consider using the following:

    Calendar cal = Calendar.getInstance(); 
            cal.set(Calendar.HOUR, 0); 
            cal.set(Calendar.HOUR_OF_DAY, 0); 
            cal.set(Calendar.MINUTE, 0); 
            cal.set(Calendar.SECOND, 0); 
            cal.set(Calendar.MILLISECOND, 0); 
            currentDate = new java.sql.Date(cal.getTimeInMillis());