Before I begin, this post is meant as a discussion point, not a flame war. I decided to publish this as a blog instead of an email on one of the JSF mailing lists so that I could get comments and feedback from others.
I have been using JSF for almost two years now, one year as my full time job. It is by far, better than any other server side framework that I have used (C CGI, Perl CGI, PHP, ASP, ASP.NET, JSP and servlets)
With this in mind, it doesn't mean there aren't issue in the JSF space. One of which is it's compatibility with AJAX. Several competitors are available to use AJAX with JSF:
- JBoss-Seam (in the works)
Each of them handle AJAX in their own way unfortunately for the learning user. The one large problem with them, is that they are all on top of JSF. Before you post your comment, here me out. JSF is a "hack" to bring a new technology on top of JSP. It was developed when Sun and Java developers realized that JSP was not succeeding and had fundemental flaws in the design that made ASP.NET, RoR and other languages more appealing. Many went the way of Struts with Java to gain so of that functionality. The problem with struts is that it never provided a good component framework.
The reason that JSF is a "hack" is that it is built from JSP pages. Although nice to those wishing to convert their projects from plain JSP to JSF with a JSP view handler, the combination is useless for large business applications. "The reason for this?" you ask, well it is the component tree. The single worst design of JSF is the saved component state of the UIViewRoot object. The component tree is made to be built once and then saved on the client or in the user's HttpSession object. This is more than just a serialized set of objects. It has methods for saving state and restoring state that custom components may override. Every time a view is restored, then entire component tree must be recursed and each of these methods are invoked. All the EL expressions (a.k.a. value bindings), component properties, attributes, etc. are all serialized into this component state. The overhead is gigantic.
To illustrate this point, let me bring up my companies application. It is just that an application, having dockabe frames, complex dialog box, complex layouts, etc. It actually makes Gmail and Google calendar look simplistic. Now I am not trying to pat myself or my company on the back, but let you know of the complexity of each view. There are hundreds if not thousands of components in this component tree. Each time I POST back to the view, the time it takes to restore this component tree is getting slower and slower as we add more functionality.
Luckily we use Facelets for our view handler not JSP (which I would never recommend as a long term solution). JSP should be though of only as a stepping stone until you convert your legacy application from JSP to JSF. Once you are completely in JSF, use facelets. It is the only way to achieve adequate performance for anything besides a Hello World application.
We are using AjaxAnywhere right now. It is very stable in 188.8.131.52 and does the job nicely. If I were to do it all again, I would probably use Ajax4Jsf due to its tight integration with JSF and the fact that it is the closest in design to Avatar (the future of AJAX in JSF from Sun).
For each AJAX request, the "JSF integrated" technologies must post back to JSF. They then execute the standard JSF lifecycle. This includes the restoring of the component tree. Yes, this is the single worst part of JSF for AJAX. If I simply want to update 2 components on the page, I have to restore the entire tree, counting possibly into the 1000s of components. Sound like a bottleneck? It is!
What can be done? Well many of these technologies "hack and slash" their way into the JSF APIs to try to speed performance. They skip phases such as validation, updating of the model, etc. for components that do not need to change, but the component tree is still always restored. The one solution is that the component tree must go! That is right, in order for JSF to have adequate performance the JSF specifications must be completely changed to mostly remove the component tree. If I want to update 2 components using AJAX, only those two components should be reloaded from the view, no more. This is problematic as the API is not built for this.
Jacob Hookom has had some really good insights on this issue:
Is the grass greener?
On the other hand GWT doesn't look like a good tool to create web pages though. There is no HTML for developers, only Java code. WYSIWYG is next to impossible from what I see for complex applications. The ease of using the JSF view and the Facelets templates, just doesn't seem to be there.
As I mentioned, the whole point of this blog is simply to start a discussion. I would love to hear what the JSF experts have to say and if they know if future releases beyond 1.2 will start to address these issues (I even wonder if 1.2 will ever take off as ppl. aren't even fully embracing 1.1 yet).
Is there something I missed with these JSF AJAX libraries to get around the component tree performance issue?
Please keep the comments to Java based technologies as they apply to JSF, this is not meant to be language war.
Since I created this post, I have had the opportunity to convert my company's software over from AjaxAnywhere to Ajax4Jsf and I wanted to report my findings so far. After some initial issues on converting some very large (and nested) templates over and converting some complex in-house components to A4J, we are now running on A4J with only some minor patching.
So even though JSF needs some large improvements to the specification to make AJAX fit better, the performance is definitely dependent on the AJAX tools used. Hopefully we see JSF more stream-lined and less JSP dependent (or hopefully completely separate from JSP) in JSF 2.0 with some improvements to component creation and state saving (letting the view handler take more of the burden on and less on the component develeper).