Reputation: 2622
I added to my application a life cycle listener inspired from a tutorial from BalusC code, and added timestamps to monitor how much time takes each phase. I was expecting that the "Invoke application" phase would take the longest time, but the log made me realize that it took about 827ms, while the "render response" phase took 2890ms and then I am wondering what is taking so much time during the "render response" phase.
As far as I understood the specification after a quick look, the only thing done during this phase is just about "rendering" (and also saving the state of the response, but does not matter here) while all application code should have been called earlier. Is it always true?
For example if my page contains a form which default value is #{myBean.valueAfterPost}, is the getter for valueAfterPost called during "Invoke application", or during "render response"?
And what is susceptible of consuming a lot of time during the render response phase?
Upvotes: 0
Views: 2759
Reputation: 31651
It can easily take more time if the content to render is complex (requires lot of evaluation) or if you've got some logic in your getter methods, which you have to avoid in any case as you can't control when getters will be invoked by the framework. Remind that JSF builds the whole view based in your model at this phase.
Action methods are called while INVOKE APPLICATION, as long as getters are invoked during RENDER RESPONSE (or they should if application is well designed).
In order to provide a kickoff example, just checked this code with a PhaseListener
:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:head />
<h:body>
<h:form>
<ui:repeat var="str" value="#{bean.strings}">
#{str}
</ui:repeat>
<h:commandButton value="send" action="#{bean.action}" />
</h:form>
</h:body>
</html>
@ManagedBean
@ViewScoped
public class Bean implements Serializable {
List<String> strings = Arrays.asList("item1", "item2");
public List<String> getStrings() {
System.out.println("Get called");
return strings;
}
public void action() {
System.out.println("Strings " + strings + " sent");
}
}
This will bring this output at first hit:
RESTORE_VIEW 1 started
RESTORE_VIEW 1 finished
RENDER_RESPONSE 6 started
Get called
Get called
RENDER_RESPONSE 6 finished
Note the getter is getting called two times, you actually have no control about how many times will the getters be called, that's why you don't have to do any logic in your getters.
Later on, if submitting the form, we've got this output:
RESTORE_VIEW 1 started
Get called
Get called
RESTORE_VIEW 1 finished
APPLY_REQUEST_VALUES 2 started
Get called
APPLY_REQUEST_VALUES 2 finished
PROCESS_VALIDATIONS 3 started
PROCESS_VALIDATIONS 3 finished
UPDATE_MODEL_VALUES 4 started
UPDATE_MODEL_VALUES 4 finished
INVOKE_APPLICATION 5 started
Strings [item1, item2] sent
INVOKE_APPLICATION 5 finished
RENDER_RESPONSE 6 started
Get called
Get called
RENDER_RESPONSE 6 finished
In this case getter method is called during RENDER RESPONSE but also at RESTORE VIEW and APPLY REQUEST VALUES. Jsf accesses the action method during INVOKE APPLICATION.
Upvotes: 5