Well, well – a full 82 days have passed since my initial statement of intent and I am finally moved to make a first meaningful blog post. Although a little abashed that it has taken so long, I am comforted by the thought of a phrase often used by my late Grandfather:
The trees that are slow to grow bear the best fruit.
I have waited nigh on thirty five years for the opportunity to use that particular quote in a written article, although I did use it once in a futile discussion about rapidly disappearing deadlines with a humourless project manager.
Humour was a commodity my Grandfather was not short of together with an abundance of wisdom and he also imparted to me the following words of advice:
There are three things in life you do not want to understand the inner workings of:
1. How sausages are made.
2. How laws are passed in a (supposedly) western democracy.
3. The JSF lifecycle.
I am fairly sure that he was definitely correct about number one and probably also number two. However, it turns out that for all his years of accumulated knowledge my Grandfather’s advice in respect of the JSF lifecycle was misguided.
Now, to be perfectly clear, this small article is by no means a deep dive into the JSF lifecycle from the perspective of an XPages developer but is simply a tip on one small feature that (along with many others) can improve the performance of your applications.
There are six phases to the JSF lifecycle:
- Restore View
- Apply Request Values
- Process Validations
- Update Model Values
- Invoke Application
- Render Response
Components on the XPage can be calculated in more than one phase of the JSF lifecycle. To give just one example, SSJS in a computed field is evaluated in the Apply Request Values and the Render Response phases.
What can be surprising to learn is that a rendered property is evaluated in no less than four of the six phases, namely Apply Request Values, Process Validation, Update Model Values and Render Response.
This should give pause for thought and if nothing else is a convincing argument for the use of Partial Execution (so only the components within the execID are recalculated during the JSF lifecycle). The estimable Mr Withers explains Partial Execution here and if you are not already familiar with this XPages feature then I urge you to stop reading this drivel and click on the aforementioned link this instant.
Now imagine if we have some heavy lifting SSJS as part of a rendered calculation or worse, several of them perhaps doing expensive look ups. These evaluations are being performed three times more than we instinctively think.
This is where view.isRenderingPhase() becomes very useful. This simple method returns true or false dependent upon whether the current lifecycle phase is Render Response.
Consider the code snippet below. This is a simple XPage with two computed fields and a button that does a full refresh (this could be a partial refresh and the full XPage component tree would still be calculated by the server unless partial execution is used).
Each computed field has a rendered property that is calculated using SSJS. There is a comment where the heavy lifting code would be in a real world application and a simple print statement to the console.
If you copy and paste this code into an XPage, view it, click the button and examine the output to the console you will see that the rendered code for the first computed field is calculated four times as outlined above.
The code for the second computed field which has a conditional check using view.isRenderingPhase() is only evaluated the once. This is highlighted in lines 18 – 25.
This can be a very useful technique in certain scenarios and used together with other powerful XPages features such as partial execution, partial refresh and the loaded property can really make a difference to application performance.
As my Grandfather would undoubtedly say
Job’s a good’un