Expert Tips and Tricks to Optimize the Performance of Your XPages Applications Bruce Elgort Elguji Software © 2012 Wellesley Information Services. All rights reserved. In This Session ... • • • Users expect that applications are fast and responsive Isn’t it funny how you only hear from them when they are slow and poorly designed XPages does all this for me, right? Nope. XPages gives us a powerful set of development tools right out of the box, however … They sometimes don’t perform as well as we had hoped Or we used XPages when a classic Domino application could have done the trick This session is designed to help developers optimize the performance of their XPages applications 1 What We’ll Cover … • • • • • • Things to consider when moving applications to XPages Understanding the JSF lifecycle and how it relates to XPages application design Development best practices for performance and scalability How to identify application bottlenecks using the OpenNTF XPages Toolbox Third-party tools to help profile your applications performance Wrap-up 2 XPages Application Design Considerations • When should you: Migrate a Notes/Domino application to XPages? Avoid developing/migrating applications to XPages? Consider a “hybrid” approach? 3 Migrating an Application to XPages • Consider migrating an application to XPages if: It’s an active application that brings value to the business Functionality can be moved to the browser without much disruption and/or retraining It is not required to be used offline Notes “only” applications that now require Web browser access The applications need a facelift and/or require new functionality 4 Avoid Using XPages • You may want to avoid using XPages if: Notes encryption is required The app depends on COM for calling other applications such as Word or Excel Makes heavy use of rich text Integration with calendaring and scheduling is required You have stable complex applications that are mission-critical and running the business You have applications that are better suited for a Notes client user experience 5 When to Consider a Hybrid Approach • • A hybrid approach is one that utilizes classic Notes and Domino design elements, as well as ones developed using XPages Consider a hybrid approach when: You have Notes client apps that require Web browser and/or mobile support yet still require use of the Notes client You need to add REST services, report generation, or other services using XPages “XAgents” When you are first starting to learn XPages When only a subset of features are needed from the Web and/or mobile device 6 What We’ll Cover … • • • • • • Things to consider when moving applications to XPages Understanding the JSF lifecycle and how it relates to XPages application design Development best practices for performance and scalability How to identify application bottlenecks using the OpenNTF XPages Toolbox Third-party tools to help profile your applications performance Wrap-up 7 Understanding the JSF Lifecycle • • XPages is built on the JavaServer Faces framework It is important to understand the principles of this framework Stateful Web application architecture Component-based architecture Every tag has a server-side object representation Saving and restoring state Validation Rendering the tags/markup to the client Uses a six-phase life cycle that is extended by XPages 8 The 6 Phase JSF Request Processing Lifecycle 1. 2. 3. 4. 5. 6. Restore View – Retrieves the JSF view for the request Apply Request Values – Updates the JSF components to update their state based on values from the current request Process Validations – Validators invoked Update model values – Application data is updated with new values. Values are written to the Domino back-end document during this phase. Invoke applications – Application logic executed Render response – Generates the response and saves the state of the view 9 More on the JSF Lifecycle Phases and What They Do • • • Phases 1 and 6 are “system-level” phases They are going to happen no matter what we do to our code Phases 2, 3, 4, and 5 are “application-level phases” These phases are something we as developers can use to our advantage By understanding how we can tweak our XPages objects to make more efficient use of the JSF lifecycle We will explore how your XPages can skip some of the six phases which in turn reduce CPU utilization processing and increase speed 10 The JSF Lifecycle www.ibm.com/developerworks/library/j-jsf2/ 11 The Link Control and the JSF Lifecycle • • • Let’s start off by looking at the link control The link control is used to place a hypertext link on an XPage or in a custom control When you place the link control on your XPage and use a “simple action” to set the link you will see this in your XPage markup <a id="view:_id1:link1" href="#" class="xspLink">Link</a> When you inspect what the browser is doing when the link is clicked you will see that the browser is issuing a “POST” request to the server This is using phases 2-5 of the JSF lifecycle and is a more “expensive” operation An extra trip is being made to the server to resolve the # in the link 12 The Link Control and the JSF Lifecycle (cont.) • • • Changing the simple action to a defined page in the link properties will now generate this code <a id="view:_id1:link1" href="/xpagesplay.nsf/contact.xsp" class="xspLink">Link</a> This will eliminate the need for: A round trip to the server (POST) is now bypassed as are phases 2-5 of the JSF lifecycle Use direct links whenever possible These will generate GET requests Save CPU time Generate a snappier user experience 13 What We’ll Cover … • • • • • • Things to consider when moving applications to XPages Understanding the JSF lifecycle and how it relates to XPages application design Development best practices for performance and scalability How to identify application bottlenecks using the OpenNTF XPages Toolbox Third-party tools to help profile your applications performance Wrap-up 14 The Read-Only Property • Setting the read-only property of a Panel in Domino Designer 15 The Read-Only Property (cont.) • • • • • Use Panel controls where no server-side JavaScript or simple actions are contained in the panel that don’t require processing Panel controls generate HTML divs which are used to place other components within Set this to true in the Properties panel Other considerations: The other thing you should consider is not using the Panel core control but rather an HTML div instead This is also true for any other HTML element that doesn’t require any processing Remember that only <xp:> tags are processed during the JSF lifecycle Setting read-only to “true” skips JSF phases 2-5 16 The Immediate Property • • This does not validate or update any data No server validation will occur No further processing of the XPages component tree will occur Just do what I say “immediately” and Cancel! Typically used on a Cancel button Set the value to true <xp:button value="Cancel" id="button2"><xp:eventHandler event="onclick" submit="true" refreshMode="complete" save="false" immediate="true"></xp:eventHandler></xp:button> • Setting the immediate property to “true” skips JSF phases 3-5 17 The Immediate Property (cont.) • • Here is our Cancel button in Domino Designer showing the “Do not validate or update data” option is checked This sets the value to true in the XPage XML source 18 Partial Refresh • A radio button under a controls Server Options that allows you to select the target component that will be refreshed Reduces the amount of HTML markup that must be processed and emitted Less HTML and other elements means that the application is more responsive The entire page does not have to be reloaded Makes Phase 6 (Render response) of the JSF lifecycle very fast and efficient Only the selected/component branch of the JSF tree is updated There may be some side effects which will require you to force the entire tree to update 19 Partial Refresh (cont.) • • If you want the server to always render the whole view tree you can: Add xsp.ajax.renderwholetree=true to the xsp.properties This file is in the WebContent/WEB-INF/ directory Use Partial Refresh where ever possible so only that portion of the JSF tree is processed and not the entire component tree 20 The DataCache Property • • • • Used for caching Domino view data Persisted view data consumes JVM memory Use if the view data isn’t needed in a POST request Three values are supported for the DataCache property: Full [default] The entire view is persisted ID Minimal scalar data ID and position. Access to column values during a POST are not available. None Enough said – the entire view needs to be reconstructed 21 Partial Execution • • • Controls how much component tree processing happens during phases 2-5 of the JSF lifecycle Partial Execution is purely a server-side optimization Partial Refresh and Partial Execution are mutually exclusive and do not depend on each other in any way 22 Partial Execution (cont.) • • • Set the execMode property on server events using: “Set partial execution mode” in the Server Settings section The default is “complete” and when checked is set to “partial” Very powerful when used inside of a View Panel, Data Table, or Repeat Control Child controls can have this property set which will not cause the parent control to not be re-executed during invocation of a child event handler Did I mention that this is very powerful and you should carefully review your code to ensure that you are taking advantage of Partial Execution wherever possible? 23 Exploring the XPages Request Processing Lifecycle • • • • So how do you know when and where your code is executing in the JSF Lifecycle? Couple this with Partial Refresh and Partial Execution of controls and things can become pretty complex exponentially. IBM’s Tony McGuckin has posted code on the OpenNTF Xsnippets site that will help you learn more about the JSF lifecycle. It will also clearly show you which phase(s) of the lifecycle your code is being executed. A sample XPage is included. http://openntf.org/XSnippets.nsf/snippet.xsp?id=xpa ges-request-processing-lifecycle-explorer-code... 24 The Sample XPage • The sample XPage that we are going to examine has: The XPage view has the following event handlers defined: beforePageLoad afterPageLoad afterRestoreView beforeRenderResponse afterRenderResponse Each of these events has a print statement that will print out to the Domino console Let’s look at the page design and them walk through some of examples 25 Sample Lifecycle XPage Layout Domino Designer Design View 26 Sample Lifecycle XPage Layout (cont.) Web browser view 27 LifeCycle.nsf Page Initial Load Output • All of the controls are rendered and then JSF Phase 6 28 P2 Button Clicked Output • • Button P2’s onclick event is set to Partial Refresh of the P2 panel Partial Execution Mode has also been selected with an execId of P2 29 P2 Immediate Button Clicked Output • • • • Button P2’s click event is set to Partial Refresh of the P2 panel Partial Execution Mode has also been selected and set to execId P2 The immediate property of the button’s onclick event has been set which will bypass any validation Typically used to save a document in draft form 30 P2 Button Disable Validators Clicked • • • Button P2’s click event is set to Partial Refresh of the P2 panel Partial Execution Mode has also been selected and set to execId P2 The “Process data without validation” checkbox is enabled (disableValidators=“true”). All phases are executed. 31 P1 Button Clicked • • • Button P1’s click event is set to Partial Refresh of the P1 panel Partial Execution Mode has also been selected and set to execId P1 Pretty much what we expected 32 P1 Button Immediate Clicked • • • Button P1’s click event is set to Partial Refresh of the P1 panel Partial Execution Mode has also been selected and set to execId P1 The immediate property of the button’s onclick event has been set which will bypass any validation 33 P1 Button Disable Validators Clicked • • • Button P1’s click event is set to Partial Refresh of the P1 panel Partial Execution Mode has also been selected and set to execId P1 The “Process data without validation” checkbox is enabled (disableValidators=“true”). All phases are executed. 34 P2 No ID Partial Execute/Full Refresh • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 08:46:14 08:46:14 08:46:14 08:46:14 08:46:14 08:46:14 08:46:14 08:46:14 08:46:14 08:46:14 08:46:14 08:46:14 08:46:14 08:46:14 08:46:14 08:46:14 08:46:14 08:46:14 08:46:14 08:46:14 08:46:14 08:46:14 08:46:14 08:46:14 08:46:14 08:46:14 08:46:14 08:46:14 08:46:14 08:46:14 08:46:14 08:46:14 08:46:14 08:46:14 08:46:14 AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: Request: Started... Lifecycle: Page: Lifecycle: Before Phase: RESTORE_VIEW 1 view1->afterRestoreView After Phase: RESTORE_VIEW 1 Lifecycle: Control: Lifecycle: Before Phase: APPLY_REQUEST_VALUES 2 txt2->rendered After Phase: APPLY_REQUEST_VALUES 2 Lifecycle: Control: Lifecycle: Before Phase: PROCESS_VALIDATIONS 3 txt2->rendered After Phase: PROCESS_VALIDATIONS 3 Lifecycle: Control: Lifecycle: Before Phase: UPDATE_MODEL_VALUES 4 txt2->rendered After Phase: UPDATE_MODEL_VALUES 4 Lifecycle: Lifecycle: Before Phase: INVOKE_APPLICATION 5 After Phase: INVOKE_APPLICATION 5 Lifecycle: Page: Control: Control: Control: Page: Lifecycle: Before Phase: RENDER_RESPONSE 6 view1->beforeRenderResponse txt1->rendered txt2->rendered txt3->rendered view1->afterRenderResponse After Phase: RENDER_RESPONSE 6 Request: Completed. 35 P2 Full Execute/Partial Refresh • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 08:49:31 08:49:31 08:49:31 08:49:31 08:49:31 08:49:31 08:49:31 08:49:31 08:49:31 08:49:31 08:49:31 08:49:31 08:49:31 08:49:31 08:49:31 08:49:31 08:49:31 08:49:31 08:49:31 08:49:31 08:49:31 08:49:31 08:49:31 08:49:31 08:49:31 08:49:31 08:49:31 08:49:31 08:49:31 08:49:31 08:49:31 08:49:31 08:49:31 08:49:31 08:49:31 08:49:31 08:49:31 08:49:31 08:49:31 08:49:31 AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: Request: Started... Lifecycle: Page: Lifecycle: Before Phase: RESTORE_VIEW 1 view1->afterRestoreView After Phase: RESTORE_VIEW 1 Lifecycle: Control: Control: Control: Lifecycle: Before Phase: APPLY_REQUEST_VALUES 2 txt1->rendered txt2->rendered txt3->rendered After Phase: APPLY_REQUEST_VALUES 2 Lifecycle: Control: Control: Control: Lifecycle: Before Phase: PROCESS_VALIDATIONS 3 txt1->rendered txt2->rendered txt3->rendered After Phase: PROCESS_VALIDATIONS 3 Lifecycle: Control: Control: Control: Lifecycle: Before Phase: UPDATE_MODEL_VALUES 4 txt1->rendered txt2->rendered txt3->rendered After Phase: UPDATE_MODEL_VALUES 4 Lifecycle: Event: Lifecycle: Before Phase: INVOKE_APPLICATION 5 p2->partial refresh value: 123 After Phase: INVOKE_APPLICATION 5 Lifecycle: Page: Control: Page: Lifecycle: Before Phase: RENDER_RESPONSE 6 view1->beforeRenderResponse txt2->rendered view1->afterRenderResponse After Phase: RENDER_RESPONSE 6 Request: Completed. 36 P2 Partial Execute/Partial Refresh • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 08:50:53 08:50:53 08:50:53 08:50:53 08:50:53 08:50:53 08:50:53 08:50:53 08:50:53 08:50:53 08:50:53 08:50:53 08:50:53 08:50:53 08:50:53 08:50:53 08:50:53 08:50:53 08:50:53 08:50:53 08:50:53 08:50:53 08:50:53 08:50:53 08:50:53 08:50:53 08:50:53 08:50:53 08:50:53 08:50:53 08:50:53 08:50:53 08:50:53 08:50:53 08:50:53 AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: Request: Started... Lifecycle: Page: Lifecycle: Before Phase: RESTORE_VIEW 1 view1->afterRestoreView After Phase: RESTORE_VIEW 1 Lifecycle: Control: Lifecycle: Before Phase: APPLY_REQUEST_VALUES 2 txt2->rendered After Phase: APPLY_REQUEST_VALUES 2 Lifecycle: Control: Lifecycle: Before Phase: PROCESS_VALIDATIONS 3 txt2->rendered After Phase: PROCESS_VALIDATIONS 3 Lifecycle: Control: Lifecycle: Before Phase: UPDATE_MODEL_VALUES 4 txt2->rendered After Phase: UPDATE_MODEL_VALUES 4 Lifecycle: Lifecycle: Before Phase: INVOKE_APPLICATION 5 After Phase: INVOKE_APPLICATION 5 Lifecycle: Page: Control: Page: Lifecycle: Before Phase: RENDER_RESPONSE 6 view1->beforeRenderResponse txt2->rendered view1->afterRenderResponse After Phase: RENDER_RESPONSE 6 Request: Completed. 37 P1 No ID Partial Execute/Full Refresh • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 08:55:07 08:55:07 08:55:07 08:55:07 08:55:07 08:55:07 08:55:07 08:55:07 08:55:07 08:55:07 08:55:07 08:55:07 08:55:07 08:55:07 08:55:07 08:55:07 08:55:07 08:55:07 08:55:07 08:55:07 08:55:07 08:55:07 08:55:07 08:55:07 08:55:07 08:55:07 08:55:07 08:55:07 08:55:07 08:55:07 08:55:07 08:55:07 08:55:07 AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: Request: Started... Lifecycle: Page: Lifecycle: Before Phase: RESTORE_VIEW 1 view1->afterRestoreView After Phase: RESTORE_VIEW 1 Lifecycle: Lifecycle: Before Phase: APPLY_REQUEST_VALUES 2 After Phase: APPLY_REQUEST_VALUES 2 Lifecycle: Lifecycle: Before Phase: PROCESS_VALIDATIONS 3 After Phase: PROCESS_VALIDATIONS 3 Lifecycle: Lifecycle: Before Phase: UPDATE_MODEL_VALUES 4 After Phase: UPDATE_MODEL_VALUES 4 Lifecycle: Event: Lifecycle: Before Phase: INVOKE_APPLICATION 5 no id->partial execute value: 123 After Phase: INVOKE_APPLICATION 5 Lifecycle: Page: Control: Control: Control: Page: Lifecycle: Before Phase: RENDER_RESPONSE 6 view1->beforeRenderResponse txt1->rendered txt2->rendered txt3->rendered view1->afterRenderResponse After Phase: RENDER_RESPONSE 6 Request: Completed. 38 P1 No ID Full Execute/Partial Refresh • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 08:56:40 08:56:40 08:56:40 08:56:40 08:56:40 08:56:40 08:56:40 08:56:40 08:56:40 08:56:40 08:56:40 08:56:40 08:56:40 08:56:40 08:56:40 08:56:40 08:56:40 08:56:40 08:56:40 08:56:40 08:56:40 08:56:40 08:56:40 08:56:40 08:56:40 08:56:40 08:56:40 08:56:40 08:56:40 08:56:40 08:56:40 AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: Request: Started... Lifecycle: Page: Lifecycle: Before Phase: RESTORE_VIEW 1 view1->afterRestoreView After Phase: RESTORE_VIEW 1 Lifecycle: Control: Control: Control: Lifecycle: Before Phase: APPLY_REQUEST_VALUES 2 txt1->rendered txt2->rendered txt3->rendered After Phase: APPLY_REQUEST_VALUES 2 Lifecycle: Control: Control: Control: Lifecycle: Before Phase: PROCESS_VALIDATIONS 3 txt1->rendered txt2->rendered txt3->rendered After Phase: PROCESS_VALIDATIONS 3 Lifecycle: Control: Control: Control: Lifecycle: Before Phase: UPDATE_MODEL_VALUES 4 txt1->rendered txt2->rendered txt3->rendered After Phase: UPDATE_MODEL_VALUES 4 Lifecycle: Event: Lifecycle: Before Phase: INVOKE_APPLICATION 5 no id->partial refresh value: 123 After Phase: INVOKE_APPLICATION 5 39 P1 No ID Full Execute/Partial Refresh (cont.) • • • • • • • • • • • 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 08:56:40 08:56:40 08:56:40 08:56:40 08:56:40 08:56:40 08:56:40 08:56:40 08:56:40 08:56:40 08:56:40 AM AM AM AM AM AM AM AM AM AM AM HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP HTTP JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: JVM: Lifecycle: Page: Control: Control: Control: Page: Lifecycle: Before Phase: RENDER_RESPONSE 6 view1->beforeRenderResponse txt1->rendered txt2->rendered txt3->rendered view1->afterRenderResponse After Phase: RENDER_RESPONSE 6 Request: Completed. 40 P1 No ID Partial Execute/Partial Refresh • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 05/10/2012 09:00:19 09:00:21 09:00:21 09:00:21 09:00:21 09:00:21 09:00:21 09:00:21 09:00:21 09:00:21 09:00:21 09:00:21 09:00:21 09:00:21 09:00:21 09:00:21 09:00:21 09:00:21 09:00:21 09:00:21 09:00:21 09:00:21 09:00:21 09:00:21 09:00:21 09:00:22 09:00:22 09:00:22 09:00:22 09:00:22 09:00:22 09:00:22 09:00:22 09:00:22 09:00:22 AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM AM Finished replication with server NA1/ideaExchange HTTP JVM: HTTP JVM: Request: Started... HTTP JVM: HTTP JVM: Lifecycle: Before Phase: RESTORE_VIEW 1 HTTP JVM: Page: view1->afterRestoreView HTTP JVM: Lifecycle: After Phase: RESTORE_VIEW 1 HTTP JVM: HTTP JVM: HTTP JVM: Lifecycle: Before Phase: APPLY_REQUEST_VALUES 2 HTTP JVM: Lifecycle: After Phase: APPLY_REQUEST_VALUES 2 HTTP JVM: HTTP JVM: HTTP JVM: Lifecycle: Before Phase: PROCESS_VALIDATIONS 3 HTTP JVM: Lifecycle: After Phase: PROCESS_VALIDATIONS 3 HTTP JVM: HTTP JVM: HTTP JVM: Lifecycle: Before Phase: UPDATE_MODEL_VALUES 4 HTTP JVM: Lifecycle: After Phase: UPDATE_MODEL_VALUES 4 HTTP JVM: HTTP JVM: HTTP JVM: Lifecycle: Before Phase: INVOKE_APPLICATION 5 HTTP JVM: Event: no id->partial refresh/execute HTTP JVM: Lifecycle: After Phase: INVOKE_APPLICATION 5 HTTP JVM: HTTP JVM: HTTP JVM: Lifecycle: Before Phase: RENDER_RESPONSE 6 HTTP JVM: Page: view1->beforeRenderResponse HTTP JVM: Control: txt1->rendered HTTP JVM: Control: txt2->rendered HTTP JVM: Control: txt3->rendered HTTP JVM: Page: view1->afterRenderResponse HTTP JVM: Lifecycle: After Phase: RENDER_RESPONSE 6 HTTP JVM: HTTP JVM: Request: Completed. value: 123 41 New in Domino 8.5.3 • Use runtime optimized JavaScript and CSS resources 42 New in Domino 8.5.3 (cont.) • Before and after 43 New in Domino 8.5.3 (cont.) • • • • Pre-load XPage engine to improve startup times – XPagesPreload=1 in notes.ini You can now “pre-load” XPages Java code into memory This makes your apps more responsive on first use In your notes.ini file you can specify which databases to pre-load: XPagesPreloadDB=servername!!path/mydb.nsf/myxpage.xsp,se rvername!!path/anotherdb.nsf 44 Single Copy XPage Design (SCXD) • New with Domino 8.5.2 www-10.lotus.com/ldd/ddwiki.nsf/dx/Single_Copy_XPage_Design 45 Single Copy XPage Design (SCXD) (cont.) • • • • • Allows lots of applications using the same template to share XPage code Saves loading more XPages into server memory Good example is the Discussion template Another example is from XPages developer Declan Lynch who has 96,000 databases which share the same design thus saving approximately 6mb per database (that’s 562gb!) You will need to restart HTTP in order for new design changes to be picked up by databases relying on your SCXD database A note on SCXD (Single Copy XPage Design), IBM fixed a high severity 8.5.3 bug (PHAN8N3HZ9) where the SCXD would timeout causing an exception under a certain scenario. This fix will be available in FP1. A Hot fix is also available. 46 Quick Performance Hits • • • • • Give the server lots and lots and lots of RAM. And then some more. Rinse and repeat. Use a 64-bit OS whenever possible Devote fast disk or SSD to your servers’ program files volume – This is where the XPages code is called from Isolate heavily used XPages apps, especially from other memory intensive apps such as Traveler Consider dedicated Domino instances for large applications 47 Setting the Data Scope for a View • • • When you add data sources to your XPage, each one has a “scope” It’s set under All Properties in the XPage Data, name, scope The default is “viewScope” Data is stored as part of the page If you want to cut down on as much memory usage as possible, and you are not relying on pass through parameters like a filter or a search Set the value of scope to “request” 48 Let’s Get Synchronized • • • • Every bit of performance we can gain is a good thing for the person using our XPages applications Many applications have several commonly used pieces of code that get executed over and over again An example would be an application that has a “control panel” type of interface This interface allows you to configure and enable/disable features and functions in the application Having your application constantly calling the same code over and over again is not efficient There is a better way to handle these types of situations Synchronize to the rescue … 49 Let’s Get Synchronized (cont.) • • • • Java has a “synchronized” keyword This keyword is now available for you to use in your ServerSide JavaScript code What does it do? It prevents the same code block from running concurrently when being called by multiple areas of the system Subsequent calls get queued up and are executed one after another The results can then be cached The queued up calls can get the result from memory (applicationScope for example) No need to recalculate over and over again Let’s look at some code … 50 Let’s Get Synchronized (cont.) function getControlPanelFieldString(fieldname) { synchronized(applicationScope) { if (isCacheInvalid("controlpanel_" + fieldname, 600)) { var controlPanels = database.getView("lookupControlPanel"); var controlPanel = controlPanels.getFirstDocument(); applicationScope.put("controlpanel_" + fieldname, controlPanel.getItemValueString(fieldname)); controlPanel = null; controlPanels = null; } } return applicationScope.get("controlpanel_" + fieldname); } • Code walkthrough Note that the code block is wrapped by synchronized{} A call to the isCachedInvalid function is made to see if the variable we need is still in the cache and is still valid based on the second parameter which is the time in seconds If the time period has expired we then perform the calculation and place in the applicationScope 51 Let’s Get Synchronized (cont.) /*A generic caching mechanism for each key will check to see if it is 'n' seconds since it was last updated. Use this for things that change relatively infrequently */ function isCacheInvalid(key, cacheInterval) { var currentTime = new Date().getTime(); if (!applicationScope.containsKey(key + "_time")) { applicationScope.put(key + "_time", currentTime); return true; } var diffInSecs = Math.ceil((currentTime - applicationScope.get(key + "_time")) / 1000); if (diffInSecs < cacheInterval) { return false; } else { applicationScope.put(key + "_time", currentTime); return true; } } • Code walkthrough (cont.) The isCacheInvalid function simply checks to see if the time has expired (cacheInterval) It returns false if it has not expired and true if it has 52 Controlling the Memory Size of the JVM on the Server • • • There are two notes.ini settings on the server that are important HTTPJVMMaxHeapSize HTTPJVMMaxHeapSizeSet The HTTPJVMMaxHeapSize parameter Specifies the maximum memory allocated to the JVM Recommended that you set to 512M or 1024M on a production server. ¼ of total RAM is a good rule of thumb. The HTTPJVMMaxHeapSizeSet parameter Ensure that HTTPJVMMaxHeapSizeSet is set to 1 to ensure that the server does not reset to 64M during a restart or upgrade 53 Application Properties • • • • • In Domino Designer each database has an Application Properties panel There are now several panels specifically for XPages settings New in 8.5.3! Package Explore > WebContent > WEB-INF > xsp.properties These values are stored in a properties file located in the xsp.persistence.* Properties basic: Keeps all pages in memory (performs well) limited to four pages file: Keep all files on disk fileex: Keeps only the current page in memory (scales and performs well) 54 XPage Application Properties 55 View Design Considerations • • • • Carefully review the structure and settings of your views The same rules apply for using views within XPages Well-performing and tuned views are critical well-performing XPage applications Some golden rules for views Limit the number of sorted columns Unnecessary columns Overly complex formulas @Now or @Today in formulas 56 What We’ll Cover … • • • • • • Things to consider when moving applications to XPages Understanding the JSF lifecycle and how it relates to XPages application design Development best practices for performance and scalability How to identify application bottlenecks using the OpenNTF XPages Toolbox Third-party tools to help profile your applications performance Wrap-up 57 The OpenNTF XPages Toolbox The XPages toolbox proposes a set of tools useful to the XPages developer, including a full fledged CPU profiler and memory profiler. Moreover, it is based on an extensible architecture aimed to host other services for developers. Available as an open source project on OpenNTF www.openntf.org/projects/pmt.nsf/Project Lookup/XPages%20Toolbox 58 What You Will Learn About the XPages Toolbox • • • • • • What “exactly” you can do with the toolbox How to install it on your Domino server Verify that it is installed correctly and running Take a quick tour of the XPages Toolbox application from a Web browser Learn how to identify problem areas in your code using the CPU and Wall timers Learn how to profile sections of your code using __profile(){} code blocks 59 What You Can Do with the XPages Toolbox • The XPages Toolbox has five key features: 1. The CPU profiler 2. The back-end classes profiler 3. The memory profiler 4. Runtime monitoring 5. Java logging groups management 60 The CPU Profiler • The CPU profiler is a high-level profiler recording the XPages activity and gathering the time spent in the different parts of the XPages (JSF lifecycle, JavaScript code, and custom code) 61 CPU Time and Wall Time • • CPU time The time actually spent by the CPU executing code Wall time The real-world time elapsed between method entry and method exit If there are other threads/processes concurrently running on the system, they can affect the results 62 The Back-End Classes Profiler • • • • This module gathers, per request, how the back-end classes are being called and the time spent in each call Note that it only measures the “Wall” time When enabled, one document is created per XPages request Each document contains the information within a rich text field 63 The Memory Profiler • • Used to show the memory being used by the XPages runtime The data is presented categorized by application (NSFs) and opened sessions 64 Runtime Monitoring • • Used to grab a high-level view of the memory being used by the JVM Also records the number of active modules (NSFs) and sessions 65 Java Logging Groups Management • • • XPages takes advantage of the Java Logging API to trace what is happening in the runtime The logging levels are initially defined in a file located within the jvm directory:<domino>/jvm/lib/logging.properties The toolbox allows you to dynamically see what are the enabled groups and change their level on the fly, without having to restart the JVM 66 Installing the XPages Toolbox on Your Server The XPages Toolbox requires Domino Server V8.5.2 or greater • An Important Security Warning The memory profiler can display and store files on the server that contain information coming from some live XPages sessions Do not install on a production server Remove the toolbox NSF as soon as you’re done with it Protecting its access using ACLs Requires a modification to the servers java.policy to explicitly enable the XPages Toolbox application 67 What’s in the XPages Toolbox Download File? • • • • • com.ibm.commons.profileragent.zip The Java source code of the profiler agent java.policy Contains the policy update that you will need to make LICENSE The Apache license file NOTICE Part of the Apache license Screenshots folder Some screenshots of the XPages Toolbox 68 What’s in the XPages Toolbox Download File? (cont.) • • • • XPagesProfilerAgent.jar The Java jar file that contains the core XPages Toolbox monitoring code XPagesToolbox.nsf The Notes database that you will access from the Web to profile your XPages applications XPagesToolbox.odt The Lotus Symphony file containing the documentation XspProfilerOptionsFile.txt A file that contains information that is needed by the profiler agent This file will be referenced in a notes.ini setting 69 Installing the Java Profiler Agent • • • • The java agent is provided as a jar file (XPagesProfilerAgent.jar) that must be copied to the <domino>/xsp directory Copy the XspProfilerOptionsFile.txt file to your domino main directory Insert the following lines into notes.ini (assuming that domino is installed in c:\Domino) ; XPages Profiler JavaOptionsFile=c:\Domino\XspProfilerOptionsFile.txt If the agent is correctly installed, the Domino console should display the following message when the http task is started 70 Updating the Java Policy File • • The java policy file is located in the <domino>/jvm/lib/security directory Assuming that the NSF is not installed in a sub-directory, the following lines should be added at the end of the java.policy file grant codeBase "xspnsf://server:0/xpagestoolbox.nsf/script/-" { permission com.ibm.designer.runtime.domino.adapter.security.AdminPer mission "AdminPermission.debug";}; Be sure and save the java.policy file! 71 Installing the XPagesToolbox.nsf Database • • • • • Copy the XPagesToolbox.nsf database file to the Domino server Be sure and install it in the location specified in the “Installing the Java Profiler Agent” step Set the database ACL Don’t forget about the security warnings we mentioned! Sign the database with the appropriate ID You may need to work with your Domino Administrator on this Access the XPagesToolbox.nsf from a browser Congratulations! You are ready to start profiling 72 Installing the XPagesToolbox.nsf Database (cont.) • If the database was installed correctly you should see this screen 73 Profiling Your XPages Code with the CPU Profiler • Let’s profile a code block from an XPages application We will profile it using the Wall Timer First we will profile a Server-Side JavaScript function “as is” Then we will add some code into the function to cause it to be less efficient It’s going to feel sleepy – the code that is You will clearly be able to see how the CPU Profiler will become your new best friend 74 The JavaScript Function We Will Profile • Looks like perfectly innocent code right? Well it actually is: 75 Let’s Profile the Function • • • • Start the Wall timer by clicking the “Start Wall Time Profiler” from the XPages Toolbox CPU Profiler tab Access the Web page that uses the getImageHTML function Now stop the Wall timer by clicking the “Stop Profiler” button Take note of the getImageHTML function and the “Specific Time” Didn’t take more than a fraction of a second to complete 76 Now Let’s Make Our Sample JavaScript Function Sleepy • We have added a simple sleep statement to our JavaScript function 77 Re-Running the CPU Profiler on the Sleepy Code • Notice that the operation now took over 5 seconds 78 Profiling Specific Code Blocks • • • The XPages runtime currently monitors some well known operations, the JSF phases and data access Developers can also monitor their own code blocks in either Java or JavaScript Each block is defined by a type (a string constant) and an optional content The content is used to categorize different instances of the same type. For example, the type can be “JavaScript expression” and the content is the JavaScript code itself. Let’s look at how to monitor code blocks in JavaScript 79 Using the __profile Keyword to Monitor Code Blocks • The XPages server-side JavaScript interpreter has an extra keyword in the runtime that defines a block of code to monitor __profile(<type>[,content]) { ..... } • Here is an example monitoring a custom block of code in our getInnerHTML JavaScript function from the previous slides __profile("Developer 2011","myBlock1") { java.lang.Thread.sleep(1000); } 80 Viewing the Profile Data for Profiled Blocks • You can see in the screen below that “Developer 2011” has been profiled and is shown under the myBlock1 Content identifier that we gave it 81 Let’s Look at the Back-End Class Profiler • • Remember that when the Back-End Class Profiler is run it’s going to create a single document for the entire page load To start the profiling process click on the “Start Profiler” button To stop the profiling process click on the “Stop Profiler” button Now opening up a contact record in my XPages app generated this document 82 Let’s Look at the Back-End Class Profiler (cont.) • Here is the document that was generated Note the class names and methods that were called Note the type of operation (GET/POST) The number of calls and the time they took 83 Let’s Look at the Runtime Monitoring Screen • • Remember that Runtime Monitoring? Shows the number of running modules (NSFs) The number of active sessions It will also show you: The total memory used by the modules The amount of free memory available in the JVM The total memory allocated for the JVM 84 Let’s Look at the Runtime Monitoring Screen (cont.) • • • • You can take an initial snapshot of the runtime by clicking the “Take Snapshot” button To start monitoring click the “Start Monitoring” button To stop monitoring click the “Stop Monitoring” button You can also specify how often a snapshot will be taken 85 Looking at the Memory Inspector Tab • • Using the Memory Inspector is something reserved for those who really want to dig into the inner workings of Java The Memory Inspector generates XML files that are stored on the Domino server when the “Dump Sessions” button is clicked 86 Java Logging Groups Management • This screen simply allows you to refine the level of logging for any of the runtime and back-end classes Change the logging level for each item as you deem necessary to help you in your XPages performance tuning 87 What We’ll Cover … • • • • • • Things to consider when moving applications to XPages Understanding the JSF lifecycle and how it relates to XPages application design Development best practices for performance and scalability How to identify application bottlenecks using the OpenNTF XPages Toolbox Third-party tools to help profile your applications performance Wrap-up 88 Third-Party Client-Side Tools • • • There are many third-party tools that you can use to help profile and analyze your application Most of these tools are browser plug-ins Some are online services These tools will analyze the Web pages generated by your XPages applications and … Make recommendations on what elements of the page you can improve upon Allow you to see exactly what the browser is seeing and how your code is being loaded, executed, and rendered You should test your applications on different browsers The recommendations made by these tools are pretty much Web browser agnostic 89 The Tools We Will Be Looking At • • • Firefox Plugins YSlow Page Speed Safari and Chrome Extensions Web Inspector (WebKit) Internet Explorer 6, 7, and 8 dynaTrace AJAX Edition 90 The Tools We Will Be Looking At (cont.) • Online testing site WebPageTest.org • Other considerations There are still many organizations using IE6 believe it or not If you are a commercial developer you may find that you have to support it 91 YSlow – Firefox Plugin • YSlow Developed by Yahoo! http://developer.yahoo.com/yslow/ Assigns and overall grade to a Web page Shows grades for things such as: Putting CSS in the page head Avoid URL redirects Compress components with GZIP Use GET for AJAX requests Do not scale images in HTML And many others 92 YSlow – Firefox Plugin (cont.) • Running YSlow on the Elguji.com site Note the various grades assigned Overall grade of A Note other grades 93 Page Speed – Firefox Plugin • Running Page Speed on the IQJam.net site Overall grade of 89/100 You can expand each section for more detailed information Note similar results to YSlow 94 WebPageTest.org • A site where you enter the URL for your site and have it tested Won’t work for internal sites 95 Web Inspector – Firefox and Chrome • • Monitor elements when they are: Loading Scripting Rendering The Web Inspector in Chrome also has a nice “audit” feature Not as feature complete as YSlow and Page Speed 96 dynaTrace AJAX Edition – Internet Explorer • • Provides an overall performance report for a site in the form of a grade Identifies potential hotspots that should be looked into http://ajax.dynatrace.com/ajax/en/ 97 What We’ll Cover … • • • • • • Things to consider when moving applications to XPages Understanding the JSF lifecycle and how it relates to XPages application design Development best practices for performance and scalability How to identify application bottlenecks using the OpenNTF XPages Toolbox Third-party tools to help profile your applications performance Wrap-up 98 Additional Resources • • • • • www.OpenNTF.org OpenNFT – Open source community for Lotus Notes and Domino www.XPages.info XPages.info – A great starting point for learning XPages www.XPagesBlog.com XPages.info Blog – A blog covering all things Xpages @XPages on Twitter @OpenNTF on Twitter 99 7 Key Points to Take Home • • • • • • • Know when and where to employ XPages when developing your applications The “hybrid” development approach (XPages and classic Notes/Domino development) is extremely popular and low risk Unlike developing classic Domino applications, developing XPages applications requires that you understand the 6 phase JSF Lifecycle Learn as much you can about the various options that are available for each of the core controls as they can impact the performance of your XPage Know how to use the XPages Toolbox profiler Become familiar with and start to use the third-party tools to profile your shiny new XPages application from the Web browser Compress (when you can) CSS, JavaScript, and images 100 Your Turn! How to contact me: Bruce Elgort bruce.elgort@elguji.com 101