Posted by jhook
on January 14, 2006 at 4:26 PM PST
What if JSF components were stored in Request Scope instead of the session or client? What are the possible consequences versus the gains?
In one my last blogs on the concepts behind Avatar involved trying to gain performance via AJAX by partially processing a UIComponent tree in JSF.
I'd like to bring another possible idea up with JSF: what about treating all components as stateless? Not stateless as in Servlet-stateless, but stateless as in request scoped.
As mentioned in the Avatar blog, component tree creation is dirt cheap (especially with Facelets ). What's expensive is state saving and rendering. So here we have this idea that evolved out of Avatar about partially rendering component trees, but then there's still a state saving issue. Even though we would render only part of the document for AJAX requests, theoretically, any part of the component tree could have changed-- so the whole tree has to be saved on every request.
JSF currently allows two different modes of state saving: client and server. In current implementations of Avatar (such as Galen Dunkleberger's), state saving only works in server mode. This is because there isn't a requirement to update the client document on every request because the server manages that state for you. With client state saving, you are required to maintain state change in the client document via hidden variables and inputs. This is a big hurdle to say the least.
Well, what if we were to throw that requirement of state saving out the window? This way partial rendering, restful communication, and server load wouldn't be so much of a problem. Maybe because I've spent too much time in the 'boiler room' of JSF to see the importance of retaining state in UIComponents, but I'd like to explain some of my reasoning behind this approach in hopes of getting feedback from other developers.
There's two ways to manage state. Actually Store the result of the process, or be able to consistently repeat the process to be able to conclude the same result. Think about JSF's tree building process and the the fact that it's clearly repeatable-- structually the same and expressions can be bound on every request. So why store the same stuff for every user on your site?
 With JSF's tree building process, imperative control tags, such as JSTL, force a mark'n'sweep process on tree creation. While this does allow the page to be structually different from the previous request, it's easily avoidable by using JSF counter parts. In some cases, one could say that re-evaluating the structure of the tree on every request would be preferred.
With the new EL-API and webtier alignment with JSP, there's no longer a disconnect on variable management and attribute assignment between the evaluated JSP document and the UIComponent tree. Again, this only leans towards the fact that retaining variable/attribute state across requests (document evaluations) could be unecessary.
Compared to other frameworks, like WebWork or Struts ActionForms, you have request-scoped state to operate on in different ways. Example, you can take a WebWork action and invoke multiple methods on that object such as update, validate, execute, etc. Hey, wait! So could JSF. Why couldn't you produce a JSF UIComponent tree at the start of every request, then update it from the incoming request, possibly validate, update the model, invoke actions, and then render?
Statesaving in JSF is [really] bad in implementation. It's very much like JSP tags where all possible attributes have to be processed. Same thing with any variable state for JSF-- both within the UIComponent itself and the whole tree structure. It's not like EJB3 or Hibernate where the framework can freely managage or optimize state deltas for you since JSF lets you explicitly implement state saving, even if you don't want to. I've thought about doing automatic state saving deltas, but then I'd lose any contract with invoking the state saving template methods on UIComponent.
JSF probably does the best job (out of the MVC frameworks) of clearly separating the View from the Model and Controller via EL. Again, this introduces an interesting point such that anything we would want to retain reference to within the JSF lifecycle and state saving-- is defined by a [static] EL expression that can be assigned and evaluated, disjoint from the UIComponent's state.
As we move into more client-side functionality with JSF and AJAX or simply client side DOM, it may introduce a disconnect between the captured state and the actual state the client sees. Then being able to 'lighter' requests back to the server becomes much more important (Avatar) and state saving of the perceived server state becomes [unecessary] overhead.
At this point you may think I'm either really dense or just maybe have a point. Again, I haven't had a chance to look at other people's components and what they require for state saving. Please let me know your thoughts and requirements where not saving state would cause problems for your components.
Truthfully, I see some issues with this approach, but they aren't without their own work arounds...