In the previous two parts of this series I’ve focussed on partial refresh and partial execution. But in order to fully appreciate why partial execution is important, you need to understand the JSF lifecycle. Part two focussed on what gets processed from the XPage, it’s important to understand how it gets processed. Remember that if execMode=”partial”, then the following phases only run for the execId. Outside of that area, nothing gets written back to the server and nothing gets recalculated.
Phase 1: Restore View
Previously I mentioned there is a server-side map of the XPage and it’s current state – the component tree. The first phase is to restore the component tree, so any changes from the latest submission from the browser can be applied.
Phase 2: Apply Request Values
Now any editable content added via the browser is extracted from the submission from the browser and stored against each component. If execMode is “full” then everything entered in the browser is passed to submittedValue. If execMode is “partial” only the content within the execId is passed to submittedValue. Everything else is discarded and will not be available for your SSJS.
Remember also that the browser content comprises only strings. At this point, the content against each component is still also stored as strings, calling this.getSubmittedValue(string). In submittedValue, strings are string, numbers are strings, dates are strings.
Phase 3: Process Validation
If immediate=”false” the submittedValue for each control is now validated against any validators, unless “process data without validation” is selected. But converters are also applied, and you cannot skip converters. That means that if you have a number converter, even if you process data without validation, if a non-numerical value is entered, the XPage will still throw an error. If any errors – from converters or validators – are thrown, the JSF lifecycle is skipped through to phase 6, Render Response. That means that your SSJS will not run.
As well as basic validators, you can add custom validators – in SSJS or Java – and they will run at this point. And this is why those validators need to use getSubmittedValue() to validate the values, because the value is still in submittedValue and has not yet been moved to value.
Phase 4: Update Model Values
Now the submitted values have been tested with converters and, if not overridden, validators. They are values that can be converted to the underlying datasource’s data type. So now for each component setValue(this.getSubmittedValue()) is called, the contents are moved to value and sibmittedValue is set to null. This is why, in the normal JSF lifecycle, you call getValue() instead of getSubmittedValue().
Phase 5: Invoke Application
Unless immediate is set to “true”, it is at this point that SSJS (your application logic) is run. Remember again that if execMode is “partial”, the only content just entered in the browser that you can use, is what is within the execId.
Phase 6: Render Response
Now, for partial refreshes, the refreshId is used. That content is passed back to the browser.
So Why Is ExecId Important
Any computed or rendered properties will also get recalculated during various phases of the JSF lifecycle. This is why execMode=”partial” and execId is important. Because those properties don’t just get recalculated once. They get recalculated a number of times. That’s because they may affect the processing. Look at the analysis below, using a PhaseListener, and measured on 8.5.3 (the stats may be better in Social Edition). I’m using 1 computed field with the value property computed using SSJS and two edit boxes with the rendered property computed. For the final two tests, execMode is set to “partial” and the execId comprises just one edit box. For two tests, the rendered property is computed in a dataContext and the edit boxes just reference that dataContext. The differences in the amount of processing is significant.
One final comment is that this investigation has given me a huge appreciation for the performance of XPages. But if you have performance issues, hopefully you have an appreciation of some steps that can be taken to improve the performance, but more importantly, enough of an understanding to refine it in a way to avoid unexpected results.