Should JSF go stateless?
Jacob Hookom's written an interesting blog entry about whether JSF could go stateless. The two of us have gone back and forth on this on e-mail a bunch of times, and I guess you could say that I fall in the "UI state is a good thing" camp. In large part, that comes from all the time I've spent working on component frameworks.
I absolutely agree with Jacob on one of his points - "Statesaving in JSF is [really] bad in implementation". It's a massive and heavyweight "save everything on the page" approach that is, at least conceptually, horrible overkill. For example, it's ridiculous that we have to save the UI component hierarchy, attributes, EL expressions, etc., when we have a JSP or Facelets document containing exactly that information just sitting there on the server. Even though I know why this happened - JSF had to support JSPs, etc., etc. - it's a very frustrating state of affairs.
Nevertheless, I think throwing out state saving altogether in response would be going too far. It'd be like saying that you should never bother sorting because Bubble Sort is a really slow algorithm. Unfortunately, JSF, as designed today, makes it very difficult to even attempt to optimize state saving. Until there's a really sane, solid implementation of state saving, any big policy decisions are premature.
The real problem with optimizing JSF state saving is the way that UIComponent.saveState() (and restoreState()) is typically implemented. Each class is responsible for saving all of its own per-instance state, up and down the hierarchy. So UIComponentBase stores its properties in an array, then UIOutput stores a few more properties (plus the UIComponentBase state) in an array of its own, then UIInput aggregates its own state, and finally HtmlInputText adds its own. For example, here's the start of HtmlInputText.saveState():
Nasty! If a container wanted to optimize state saving, it'd somehow have to mix that in not just into one class, but into every component class up and down the hierarchy.
ADF Faces took a different approach. We store all of our component state in an FacesBean instance. It takes care of storing simple properties, ValueBindings, lists (like listeners and validators), and knows how to save and restore state. Here's the full code for UIXComponentBase.saveState();
And subclasses don't neeed any code at all. Aaahhhh..... Now that's better. More on FacesBean in a later post (there's a lot of other advantages), but what's relevant is the general principle: all state saving is implemented up in the base class, so now there's a hook to implement real cross-cutting optimizations like:
Secondarily, we'd do very well to follow Jacob's advice and re-think how processSaveState() and processRestoreState() function - instead of creating a deep heirarchy, create a flattened Map or array structure.
Implement all of this, and then we're in a place to judge whether fully stateless UIs are necessary. I think they will be, for some limited types of applications, but JSF can be pushed a lot further than it's going now.
I absolutely agree with Jacob on one of his points - "Statesaving in JSF is [really] bad in implementation". It's a massive and heavyweight "save everything on the page" approach that is, at least conceptually, horrible overkill. For example, it's ridiculous that we have to save the UI component hierarchy, attributes, EL expressions, etc., when we have a JSP or Facelets document containing exactly that information just sitting there on the server. Even though I know why this happened - JSF had to support JSPs, etc., etc. - it's a very frustrating state of affairs.
Nevertheless, I think throwing out state saving altogether in response would be going too far. It'd be like saying that you should never bother sorting because Bubble Sort is a really slow algorithm. Unfortunately, JSF, as designed today, makes it very difficult to even attempt to optimize state saving. Until there's a really sane, solid implementation of state saving, any big policy decisions are premature.
The real problem with optimizing JSF state saving is the way that UIComponent.saveState() (and restoreState()) is typically implemented. Each class is responsible for saving all of its own per-instance state, up and down the hierarchy. So UIComponentBase stores its properties in an array, then UIOutput stores a few more properties (plus the UIComponentBase state) in an array of its own, then UIInput aggregates its own state, and finally HtmlInputText adds its own. For example, here's the start of HtmlInputText.saveState():
public Object saveState(FacesContext _context) {
Object _values[] = new Object[31];
_values[0] = super.saveState(_context);
_values[1] = accesskey;
_values[2] = alt;
_values[3] = dir;
_values[4] = this.disabled ? Boolean.TRUE : Boolean.FALSE;
_values[5] = this.disabled_set ? Boolean.TRUE : Boolean.FALSE;
.... and on and on and on for another 26 lines ....
}
Nasty! If a container wanted to optimize state saving, it'd somehow have to mix that in not just into one class, but into every component class up and down the hierarchy.
ADF Faces took a different approach. We store all of our component state in an FacesBean instance. It takes care of storing simple properties, ValueBindings, lists (like listeners and validators), and knows how to save and restore state. Here's the full code for UIXComponentBase.saveState();
public Object saveState(FacesContext context)
{
return getFacesBean().saveState(context);
}
And subclasses don't neeed any code at all. Aaahhhh..... Now that's better. More on FacesBean in a later post (there's a lot of other advantages), but what's relevant is the general principle: all state saving is implemented up in the base class, so now there's a hook to implement real cross-cutting optimizations like:
- Cache reusable FacesBean instances on a Facelet tag handler (with copy-on-write), especially for panels and output components that rarely if ever mutate
- Implement saveState() that only saves deltas from the original state of the bean (and rely on Facelets to recreate the tree in its original state)
Secondarily, we'd do very well to follow Jacob's advice and re-think how processSaveState() and processRestoreState() function - instead of creating a deep heirarchy, create a flattened Map or array structure.
Implement all of this, and then we're in a place to judge whether fully stateless UIs are necessary. I think they will be, for some limited types of applications, but JSF can be pushed a lot further than it's going now.
8 Comments:
Hi.
I read your blog with interest, but some of the material is too advanced for me to understand. Can you kindly explain the issue in more elementary terms to the novice JSF programmers who are not as advanced as you are?
-thank-you
By Anonymous, at 10:37 AM
What can I say...This webpage has many pluses.
write book review
By Larah, at 7:09 AM
Although cocky and maybe naive you are correct. The F-15 still runs the show and does it with a perfect combat record. This on the other hand is just overkill wich is the way the USAF likes to keep it. I think they made these planes for a "just in case" situation. lol
By Guru1234, at 10:05 AM
Hi Adam,
Bit of a shameless plug here but would be interested in your comments on the approach we have been looking at where state can effectively be disabled on JSF.
http://industrieit.com/blog/2011/11/stateless-jsf-high-performance-zero-per-request-memory-overhead/
We see this as a means to bridge the gap between JSF and client side Javascript technology implementations.
Thoughts?
Brendan
By Brendan, at 11:06 AM
Great Article
JSF Online Training | JSF Training | JSF Training Courses | Java Training Institutes in Chennai | Java Training in Chennai | Java Course in Chennai | JSF Interview Questions | Java Training Institutes in Chennai | Java Training in Chennai
By for ict 99, at 9:42 PM
The first thing to visit this blog is useful admission-service information and add our insight and knowledge for us all and me thank you admin.. visit my website
By LauraMedley, at 3:49 AM
baseball star mod apk free download terraria game download monster legends mod apk for android
By Ali Gibson, at 10:54 PM
The blog or and best that is extremely useful to keep I can share the ideas of the future.
Motorwars2.com
Bulletforce.org
By game fan, at 1:00 PM
Post a Comment
<< Home