The process of optimizing your portlets for the best possible performance spans all phases of development. You should continually monitor performance and make appropriate adjustments.
This chapter describes performance optimizations that you can incorporate as you develop portlets.
This chapter contains the following sections:
Customizing performance-related portlet properties can help you improve performance. For example, you can set process-expensive portlets to pre-render or render in a multi-threaded (forkable) environment. If a portlet has been designed as forkable (multi-threaded) you have the option of adjusting that setting when building your portal.
The following portlet properties are performance related:
Portlet Properties includes descriptions of these properties. If you design your portlets to allow portal administrators to adjust cache settings and rendering options, you can modify those properties in the Administration Console.
You can cache the portlet within a session instead of retrieving it each time it recurs during a session (on different pages, for example). Portlets that call web services perform frequent, expensive processing; caching web service portlets greatly enhances performance. Portlet caching is well-suited to caching personalized content; however, it is not well suited to caching static content that is presented identically to all users and that rarely expires.
The ideal use case of the portlet cache is for content that is personalized for each user and expires often. In other situations, it might be more beneficial to use other caching alternatives such as using the wl:cache
tag or the portal cache.
For a detailed examination of the Render Cacheable property and a discussion of when you should or should not use it, refer to the article Portlet Caching by Gerald Nunn, available the Oracle Technology Network.
Remote portlets are made possible by Web Services for Remote Portlets (WSRP), a web services standard that allows you to “plug-and-play” visual, user-facing web services with portals or other intermediary web applications. WSRP allows you to consume applications from WSRP-compliant Producers, even those far removed from your enterprise, and surface them in your portal.
While there might be a performance boost related to the use of remote portlets, it is unlikely that you would implement them for this reason. The major performance benefit of remote portlets is that any portal framework controls within the application (portlet) that you are retrieving are rendered by the producer and not by your portal. The expense of calling the control life cycle methods is borne by resources not associated with your portal.
Implementations using remote portlets also have limitations; for example:
If the expense of portal rendering sufficiently offsets the expense of transport and the other limitations described above are inconsequential to your application, using remote portlets can provide some performance boost to your portal.
For more information on implementing remote portlets with WSRP, refer to the Federated Portals Guide.
Portlet forking allows portlets to be processed on multiple threads. Depending on the available server resources, this means that the portal page will refresh more quickly than if all portlets were processed sequentially. Forking is supported for JSP, Page Flow, Java, and WSRP portlets (consumer portlets only).
Note: | Although using this feature might reduce the response time to the user in most situations, on a heavily loaded system it can actually decrease overall throughput as more threads are being used on the server/JVM for each request—adding to contention for shared resources. |
This section includes these topics:
Forking is easy to enable – you just set properties using the portlet Properties editor in Workshop for WebLogic, as shown in Figure 7-1. The available forking properties are described in this section. For detailed information on the Portlet Properties editor, see Portlet Properties.
This property must be set to true if you want the portlet to be forked. This property identifies the portlet as safe to run forked. If this attribute is false (the default), the portlet will not be forked regardless of the settings of the other two forking properties. See Best Practices for Developing Forked Portlets for tips on developing forked portlets.
When set to true, a portal administrator can use the Run the Portlet in a Separate Thread property. If set to false, that property is not available to administrators. See the Portal Development Guide for information on using the Administration Console to edit portlet properties.
|
|
Enables forking (multi-threading) in the pre-render life cycle phase. For an overview of the portal life cycle, see Architectural Details of Forked Portlets. See also “How the Control Tree Affects Performance” in the Portal Development Guide for more information about the control tree life cycle.
Setting Fork Pre-Render to
true indicates that the portlet’s pre-render phase should be forked. See Dispatching Pre-Render Forked Portlets to Threads for more information on the pre-render phase.
|
|
If Fork Pre-Render is set to
true , you can set an integer timeout value, in seconds, to indicate that the portal framework should wait only as long as the timeout value for each fork pre-render phase. The default value is -1 (no timeout). If the time to execute the forked pre-render phase exceeds the timeout value, the portlet itself times out (that is, the remaining life cycle phases for this portlet are cancelled), the portlet is removed from the page where it was to be displayed, and an error level message is logged that looks something like the following example.
|
|
Setting to
true tells the framework that it should attempt to multi-thread render the portlet. This property can be set to true only if the Forkable property is set to true . See Dispatching Render Forked Portlets to Threads for more information on the render phase.
|
|
If Fork Render is set to
true , you can set an integer timeout value, in seconds, to indicate that the portal framework should wait only as long as the timeout value for each fork render portlet. The default value is -1 (no timeout). When a portlet rendering times out, an error is logged, but no markup is inserted into the response for the timed-out portlet.
|
The forking properties, if set, appear as XML elements a .portlet file. Listing 7-9 shows a sample of a portlet configured for both pre-render and render forking:
<netuix:portlet title="Forked Portlet"
definitionLabel="forkedPortlet1"
forkable="true"
forkPreRender="true"
forkRender="true">
<netuix:content>
<netuix:jspContent contentUri="/portlets/forked.jsp"
backingFile="backing.PreRenderBacking"/>
</netuix:content>
</netuix:portlet>
Generally, forking is easy to understand and to enable. However, with a deeper understanding of how forking works, you can avoid potential problems and unwanted side effects. This section discusses the architectural design of forked portlets. For specific implementation tips, see Best Practices for Developing Forked Portlets.
This section includes these topics:
For most requests to the portal, the total time to process the request, or request latency, is roughly related to the time needed to run through the portal life cycle phases successively for all the portlets. Each life cycle phase is performed by walking through a tree of objects, called the control tree, that make up the portal. Each phase is essentially a depth-first walk over the tree, where the root of the tree is the desktop, and the leaves of the tree are the books, pages, portlets, and other so-called controls. Figure 7-2 illustrates the general structure of a portal control tree.
Figure 7-3 illustrates the successive phases of the portal rendering life cycle. During the first traversal of the control tree, the init() method is called on each control. On the second traversal, loadState() is called, and so on, until every control is processed.
Typically, portlet processing time is dominated by the execution of business logic, especially if the portlets must access remote resources such as databases or web services, or if they are computationally intensive. Forking allows you to parallelize some of these longer running portlet operations to decrease the overall request latency. If forking is enabled, these operations are collected in a queue and dispatched to multiple threads for processing. Depending on your server’s resource availability, forking can theoretically reduce request latency to the maximum latency of any of the forked portlets.
During the pre-render phase of the portal life cycle, all portal controls are iterated and pre-rendering operations are executed. Any portlets that are marked for either pre-render or render forking are identified during this pass and, if they are marked for forking, they are placed in separate queues: a pre-render queue and a render queue. (See Configuring Portlets for Forking for details on how to mark portlets for pre-render and render forking.)
At the appropriate times, these queues are dispatched to threads and processed, as explained in the following sections. See also Threading Details and Coordination.
In the pre-render phase of the portal life cycle, portlets typically perform business logic, typically by handling postback data or by calling a backing file method, such as the AbstractJSPBacking.preRender() method.
During normal pre-render processing of the portal, any portlet that is marked for pre-render forking is placed into a queue and the pre-render processing is skipped. After the entire pre-render phase has been performed, the queue is inspected. If it is not empty, the queue is dispatched and the portlets in the queue are assigned to a worker thread. After the queue is fully dispatched, the main portal thread waits until either all the worker threads are completed or timed out.
In some cases, business logic is performed during the render phase of the portal life cycle, typically when JSP scriptlets are used.
Before running through the render life cycle, the render queue is examined. If it is not empty, the queue is dispatched and any portlets in the queue are assigned to worker threads. As with pre-render forking, the main portal thread waits until all of the render threads are either completed or timed out. The resulting buffered response from each thread is saved for each completed forked portlet. At this point, the actual render life cycle phase is run. When a portlet is encountered that was marked for forking, the render processing is skipped and the saved buffered response data for the portlet is written to into the response.
Some types of portlets, notably Struts or Page Flow portlets, provide a mapping between the underlying application technology and the portal life cycle model. Usually in these cases, actions are provided to handle business logic during the handle postback or pre-render phases of the life cycle.
The worker threads used by the forking feature are implemented as WLS WorkManager classes. WebLogic Portal does not directly allocate any threads; rather, a WorkManager is identified by its JNDI name. If found, the WorkManager is used to dispatch the worker threads (Work instances). The default WorkManager for dispatching forked portlets is called wm/forkedRenderQueueWorkManager, with a default called wm/Default. If you need to customize the WorkManager for any reason, you can specify an alternate instance through the weblogic.xml or weblogic-config.xml file by associating the alternate instance with the JNDI name wm/forkedRenderQueueWorkManager. See also Consider Thread Safety.
The framework uses a ForkedLifecycleContext object to coordinate between the mainline life cycle thread and the forked Worker instances. During initialization of a Worker, the ForkedLifecycleContext is created and registered with the forking dispatch queue. When the Work instance has completed, the ForkedLifecycleContext is set to completed and the waiting mainline thread is notified. Alternately, if the waiting mainline thread determines that the forked Work instance is taking too long and should be timed out, the ForkedLifecycleContext is marked as timed out and the Work instance is removed from the dispatch queue. Note that in this case, the Work item is not aborted, and will keep running until the portlet code being run for either the pre-render or render phase is completed. You can obtain the current ForkedPreRenderContext or ForkedRenderContext using a utility method on those classes from the request. You can then check if a timeout has been set to detect cases where the Worker thread was timed out by the portal framework and should be aborted.
Regardless of whether or not you use render forking, the portal does not render until all portlets complete rendering. If you want portlets to render individually, you can use asynchronous portlet rendering.
Asynchronous portlet content rendering refers to page processing that occurs on the client browser; multiple threads are spawned, using AJAX or IFRAME technology. Asynchronous portlet rendering allows the contents of a portlet to render independently from the surrounding portal page. This can provide a significant performance boost; for example, when a portal visitor works within a portlet, only that individual portlet needs to be redrawn.
WARNING: | Using forked rendering with asynchronous portlet content rendering is unnecessary, is not recommended, and could result in unexpected behavior. |
For details on asynchronous rendering, see Asynchronous Portlet Content Rendering. For a comparison of portlet forking and asynchronous rendering, see Comparison of Asynchronous and Conventional or Forked Rendering.
This section discusses three primary issues you need to consider when developing forked portlets: thread safety, runtime environment, and interportlet communication issues.
Although the portal framework handles thread safety issues that affect the framework itself, any code you write that is intended to be used in forked portlets should be written in a threadsafe manner.
When designing forked portlets, try to maximize their independence from other constructs in the portal (such as BackingContext) and from other portlets. Such dependencies create problems for forked portlets because forked portlets are inherently isolated from the runtime environment.
The primary difference between the runtime environment for forked portlets and non-forked portlets is in their level of isolation. This difference occurs because of the way that forked portlets are collected and dispatched outside of the life cycle execution for the main portal control tree.
Each life cycle iteration of the control tree results in a life cycle method being called for that control. In this way, each control has the opportunity to perform life cycle specific business logic. Additionally, each life cycle method invocation involves both a begin and end operation, which enables setup and teardown for controls that require such functionality.
Enabling preRender or render forking moves the execution of a portlet’s life cycle processing from occurring within the main portal control tree walk to outside of it. The main side effects of this are:
As a developer of forked portlets, be aware that code meant to be executed in a forked portlet should be as stand-alone as possible. Avoid relying on interaction with other portlets, other controls higher in the control tree, or state provided by other controls in the control tree.
Do not rely on any processing done during the same life cycle in other portlets, because forking a portlet both takes it out of order with respect to control tree execution and applies an arbitrary ordering among forked portlets in the dispatch queue.
For preRender forked portlets, one of the main areas of concern for forked portlets is the BackingContext framework. This framework is managed in part by a stack-based implementation involving the request, which depends on Backable controls in the control tree to push and pop their BackingContext instances onto and off of the request. All of these activities happen during the pre-render life cycle phase. When writing a portlet that expects a particular BackingContext stack environment, problems can occur with Fork Pre-Render mode. Any access to BackingContexts through the request will result in that BackingContext not being available while forked.
To work around this BackingContext issue, you can use non-contextual methods to obtain BackingContexts for other presentation controls in the control tree, but these generally involve explicit walking of the context tree, and some contexts may be unavailable because the context in question has already been cleaned up by the control that manages it in preRender.
Interportlet communication (IPC) is another area of concern for forked portlets. Again, the more you can isolate a portlet’s logic, the more successfully it will run in a forked environment.
IPC is performed in several different life cycles. When an IPC scenario is enabled that results in an IPC call initiated during preRender, and a portlet is also enabled for forking, that IPC will not be performed, since the actual dispatch of the IPC event queue happens immediately following the main execution of preRender() over the control tree. This is of primary concern to portlets that raise IPC events in a backing file preRender() method, from a Page Flow, a Struts begin action, or from a JSF beginning view root.
Asynchronous portlet rendering allows you to render the content of a portlet independently from the surrounding portal page. This can provide a huge performance boost; for example, when a portal visitor works within a portlet, only that individual portlet needs to be redrawn.
Note: | The Collaboration portlets, such as the Calendar portlet, will not operate correctly when the desktop or portlet asynchronous mode is enabled. Async mode is not supported for Collaboration portlets. For information on Collaboration Portlets, see Using the Collaboration Portlets. |
Tip: | You can also enable asynchronous rendering for an entire portal desktop. Both portlet-specific (as discussed in this section) and desktop asynchronous rendering offer quicker response times than synchronous rendering. Note that the portlet-specific and desktop options for asynchronous rendering are mutually exclusive features. For more information on asynchronous desktop rendering and tips on deciding which method to choose, see the chapter “Designing Portals for Optimal Performance” in the WebLogic Portal Development Guide. |
You can use either AJAX technology or IFRAME technology to implement asynchronous rendering for individual portlets. When using asynchronous portlet rendering, a portlet renders in two phases. The normal portal page request process occurs first; during this process, the portlet's non-content areas, such as the title bar, are rendered. Rather than rendering the actual portlet content, a placeholder for the content is rendered. A subsequent request process displays the portlet content.
This section contains the following topics:
The portlet property asyncContent
in the Properties view allows you to specify whether to use asynchronous rendering, and to select which technology to use. An editable drop-down menu provides the selections none
, ajax
, and iframe.
If you want to create a customized implementation of asynchronous rendering, you can do so by editing the .portlet
file to set this up.
Portlet files that do not contain the asyncContent
attribute appear with the initial value none
displayed in the Properties view. Any changes to the setting are saved to the .portlet
file.
Note: | Although Browser portlets use an internal implementation that appears similar to that of an asynchronous portlet and both portlet types use IFRAME HTML elements, the actual implementations are quite different. Browser portlets are merely displaying static embedded documents, but asynchronous IFRAME portlets are managed by the framework. |
Keep the following global considerations in mind for any asynchronous rendering implementation:
If navigation is handled by the browser, the behavior of a portlet will vary according to the type of asynchronous rendering technology used, and this inconsistency can be confusing to the end user. For example, with IFRAME technology each portlet interaction is tracked, but this interaction does not update the “view” from the server’s perspective; if the user clicks the Back button, the server takes the user to a state preceding the interaction with the portlet.
com.bea.netuix.servlets.controls.portlet.PortletPresentationContext.isAsyncContent()
com.bea.netuix.servlets.controls.portlet.PortletPresentationContext.isContentOnly()
com.bea.netuix.servlets.controls.portlet.backing.PortletBackingContext.isAsyncContent()
com.bea.netuix.servlets.controls.portlet.backing.PortletBackingContext.isContentOnly()
<render:jspContentUrl>
or <netui:anchor>
. GenericURL.WINDOW_LABEL_PARAM
directly to the PostbackURL with the value returned from PortletPresentationContext.getLabel()
or PortletBackingContext.getLabel()
. If you use asynchronous portlet content rendering, be sure that your code (for example, in backing files) is thread safe. The portal framework handles the major issues outside of a developer's control, such as concurrent access to the request and response; and it manages coordination of issues such as waiting for all async operations to finish and assembling the results in the correct order. But the portlet developer has the responsibility for ensuring that the user code is thread safe.
This consideration also applies to parallel (forked) portlet processing. See Portlet Forking.
Some special considerations associated with IFRAME-based asynchronous rendering include:
<render:context>
tag or the AsyncContentContext
class as described in Disabling Asynchronous Rendering for a Single Interaction; however, these mechanisms do not work correctly when IFRAME-based asynchronous rendering is used. To avoid this issue, turn off asynchronous rendering or use AJAX-based asynchronous rendering. Some special considerations associated with Asynchronous JavaScript and XML (AJAX)-based asynchronous rendering include:
Table 7-2 summarizes the advantages and disadvantages of IFRAME- and AJAX-based asynchronous rendering. Oracle recommends AJAX as a more robust implementation.
The following table compares some of the behavior and features of conventional or forked rendering and asynchronous portlet content rendering.
This section provides more information about life cycle and control tree implications associated with using asynchronous content rendering.
For the initial request for a portal page, backing files attached to the portlet will run in the context of a full portal control tree. However, portlet content—such as Page Flows, managed beans, JSP pages, and so on—will not run for this initial request.
The values for the above-referenced APIs will be:
PortletBackingContext.isAsyncContent() = true
PortletBackingContext.isContentOnly() = false
For the subsequent content requests, backing files attached to the portlet, and the portlet content itself—such as Page Flows, managed beans, JSP pages, and so on—will run in the context of a “dummy” control tree.
The values for the above-referenced APIs will be:
PortletBackingContext.isAsyncContent() = true
PortletBackingContext.isContentOnly() = true
PortletPresentationContext.isAsyncContent() = true
PortletPresentationContext.isContentOnly() = true
An important consequence of this model is that when asynchronous content rendering is enabled for portlets, the portlet content will run in isolation from the rest of the portal. Such portlets therefore cannot expect to have direct access to other portal controls such as books, pages, desktops, other portlets, and so on.
Although IPC is not supported when asynchronous content rendering is enabled, WebLogic Portal provides some features that allow these two mechanisms to coexist in your portal environment. In addition, you can disable asynchronous rendering for single requests using the mechanisms described in this section.
This section also applies to HTTP redirects.
Note: | The techniques described in this section do not currently work with IFRAME portlets. |
Tip: | If you enable asynchronous rendering at the portal/desktop level, you can use IPC without restrictions. For more information on asynchronous portal/desktop rendering, see the WebLogic Portal Development Guide. |
For forms containing file upload mechanisms, the WebLogic Portal framework automatically causes page refreshes without the need for any workarounds.
Generally, if a portlet needs to disable asynchronous content rendering for a single interaction (such as a form submission, link click, and so on), you should use the mechanism described in this section.
Tip: | When you use these mechanisms to disable asynchronous rendering, the portlet’s action/rendering will be performed using two requests. The portlet’s action is performed in the page request, while the portlet’s rendering is performed on a subsequent request. Ensure that your action does not use request attributes to pass information to your JSP page. |
From a JSP page, use the <render:context>
tag as follows. You can find this tag in the Design Palette under Tag Libraries > Portal Framework Rendering > Context.
<render:context asyncContentDisabled="true">
Form, anchor, etc. would appear here
(that is, <netui:form action=”submit”…)
AsyncContentContext.push(request).setAsyncContentDisabled(true);
//
Code that generates a URL would appear here
AsyncContentContext.pop(request)
URL compression interferes with some of the AJAX-specific mechanisms for page refreshes. Because of this, URL compression must also be disabled whenever asynchronous content rendering is disabled to force page refreshes. WebLogic Portal disables URL compression automatically except when file upload forms are used; in this situation, you must explicitly disable it. Use the following examples as a guide:
<render:controlContext urlCompressionDisabled="true">
Form, anchor, etc. would appear here
(that is, <netui:form action=”submit”…)
UrlCompressionContext.push(request).setUrlCompressionDisabled(true);
// Code that generates a URL would appear here
UrlCompressionContext.pop(request)
For more information about implementing URL compression, refer to the Portal Development Guide.