Server Centric Java Frameworks: Performance Comparison
These days we are used to AJAX-intensive, sophisticated web frameworks. These frameworks provide us desktop style development into the Single Page Interface (SPI) paradigm. As you know there are two main types of frameworks, client-centric and server-centric. Each approach has pros and cons.
Testing the
performance of Java server-centric frameworks
In the server-centric view, state is managed in server. In some way the client is a sophisticated terminal of the server because most of visual decisions are taken on the server and some kind of visual rendering is done on the server (HTML generation as markup or embedded in JavaScript or more higher level code sent to the client). The main advantage is that data and visual rendering are together in the same memory space, avoiding custom client-server bridges for data communication and synchronization, typical of the client-centric approach.
This article only reviews Java server-centric frameworks.
In SPI, the web page is partially changed; that is, some HTML parts can be removed and some new HTML markup can be inserted. This approach obviously saves tons of bandwidth and computer power because the complete page is not rebuilt and not fully sent to the client when some page change happens.
A server-centric framework to be effective must send to the client ONLY the markup going to be changed or equivalent instructions in some form, when some AJAX event hits the server.
This article reviews how much effective most of the SPI Java web frameworks are on partial changes provided by the server. We are not interested in events with no server communication, that is, events with no (possible) server control.
How they are going to be measured
We are going to measure the amount of code that is sent to client regarding to the visual change performed in client.
For instance for a minor visual change (some new data) in a component we expect not much code from server, that is, the new markup needed as plain HTML, or embedded in JavaScript, or some high level instructions containing the new data to be visualized. Otherwise something seems wrong for instance the complete component or page zone is rebuilt, wasting bandwidth and client power (and maybe server power).
Because we will use public demos, we are not going to get a definitive and fine grain benchmark. But you will see very strong differences between frameworks.
The testing technique is very easy and everybody can do it with no special infrastructure, we just need FireFox and FireBug. In this test FireFox 3.6.8 and FireBug 1.5.4 are used.
The FireBug Console when "Show XMLHttpRequests" is enabled logs any AJAX request showing the server response.
The process is simple:
- The Console will be enabled before loading the page with the demo.
- Some clicks will drive some concrete component to the desired state.
- A final click will perform a small change in the component being analyzed.
- Then we will copy the output code of the AJAX request (HTML, XML, JavaScript ...) sent from server.
The more code the less effective, more bandwidth waste and client processing is needed.
We cannot measure the server power used because we need a deep knowledge of how the framework works in server, said this we can easily "suspect" the more code generated in server the more server power is wasted.
Frameworks tested
RichFaces, IceFaces, MyFaces/Trinidad, OpenFaces, PrimeFaces, Vaadin, ZK, ItsNat
ADF Faces is not tested because there is no longer a public live demo. Because ADF Faces is based on Trinidad, Trinidad analysis could be extrapolated to ADF Faces (?).
Update: NO, ADF Faces are very different to Trinidad.
Note before starting
Some frameworks seem to perform very well (regarding to this kind of test), that is, the ratio between visual change and amount of code is acceptable, but in some concrete cases (components) they "miserably" fail. This article tries to measure bad performant components.
RichFaces
Console must be enabled, configured and open as seen before.
- Open this tree demo (Ajax switch type)
- Expand "Baccara" node
- Expand "Grand Collection"
- Collapse "Grand Collection"
As you can see the child nodes below "Grand Collection" has been removed or hidden (FireBug's DOM inspector says they were removed).
<html xmlns="http://www.w3.org/1999/xhtml" lang="en"><head></head><body><div xmlns:rich="http://richfaces.ajax4jsf.org/rich"><table border="0" cellpadding="0" cellspacing="0" class="rich-tree-node" id="j_id354:j_id355:0:1::j_id358"><tbody><tr id="j_id354:j_id355:0:1::j_id358:mainRow" onclick=" "><td class="rich-tree-node-handleicon rich-tree-h-ic-line-node" id="j_id354:j_id355:0:1::j_id358:handles" style="background-image:expression(this.parentNode.parentNode.parentNode.nextSibling.nextSibling ? 'url(/richfaces-demo/a4j/g/3_3_3.Finalorg.richfaces.renderkit.html.images.TreeLineNodeImage/DATB/eAH7!!!!72fXGBgYACWpBbU_.jsf)' : 'url(/richfaces-demo/a4j/g/3_3_3.Finalorg.richfaces.renderkit.html.images.TreeLineLastImage/DATB/eAH7!!!!72fXGBgYACWpBbU_.jsf)')"><div><a class="rich-tree-node-handle" href="#" id="j_id354:j_id355:0:1::j_id358:handle" onclick="var c = Tree.Item.findComponent(this); if (!c) return; c.fireExpansionEvent();;A4J.AJAX.Submit('j_id354',event,{'similarityGroupingId':'j_id354:j_id355:0:1::j_id358','parameters':{'j_id354:j_id355:0:1::j_id358AjaxExpanded':true,'j_id354:j_id355:0:1::j_id358NodeExpanded':'true'} } ); return false;"><img alt="" class="rich-tree-node-handleicon-collapsed" id="j_id354:j_id355:0:1::j_id358:handle:img:collapsed" src="/richfaces-demo/a4j/g/3_3_3.Finalorg.richfaces.renderkit.html.images.TreePlusImage/DATB/eAH7!!!!72fXGBgYACWpBbU_.jsf" style=";border:0" /><img alt="" class="rich-tree-node-handleicon-expanded" id="j_id354:j_id355:0:1::j_id358:handle:img:expanded" src="/richfaces-demo/a4j/g/3_3_3.Finalorg.richfaces.renderkit.html.images.TreeMinusImage/DATB/eAH7!!!!72fXGBgYACWpBbU_.jsf" style="display: none;;border:0" /></a></div></td><td class="rich-tree-node-icon rich-tree-h-ic-line-clp" id="j_id354:j_id355:0:1::j_id358:icon" rich:draggableoptions="{'parameters':{'dragSourceId':'j_id354:j_id355:0:1::j_id358','j_id354:j_id355:0:1::j_id358':'j_id354:j_id355:0:1::j_id358'} } " rich:dropzoneoptions="{} "><img alt="" class="rich-tree-h-ic-img" src="/richfaces-demo/images/tree/disc.gif" /></td><td class="rich-tree-node-text " id="j_id354:j_id355:0:1::j_id358:text" rich:highlightedclass="rich-tree-node-highlighted" rich:selectedclass="rich-tree-node-selected">Grand Collection</td></tr></tbody></table><div id="j_id354:j_id355:0:1::j_id358:childs" style="display: none;" class="rich-tree-node-children rich-tree-h-ic-line"></div><div id="j_id354:j_id355:script" class="rich-tree-h"><script type="text/javascript">$('j_id354:j_id355').component.refreshAfterAjax(['j_id354:j_id355:0:1::j_id358'] ,'')</script></div></div><div xmlns:rich="http://richfaces.ajax4jsf.org/rich"></div><div xmlns:rich="http://richfaces.ajax4jsf.org/rich"></div><div xmlns:rich="http://richfaces.ajax4jsf.org/rich"></div><div xmlns:rich="http://richfaces.ajax4jsf.org/rich"></div><meta name="Ajax-Update-Ids" content="j_id354:j_id355:0:1::j_id358,j_id354:j_id355:0:1::j_id358:childs,j_id354:j_id355:script" /><span id="ajax-view-state"><input type="hidden" name="javax.faces.ViewState" id="javax.faces.ViewState" value="j_id3" /></span><meta id="Ajax-Response" name="Ajax-Response" content="true" /><meta name="Ajax-Update-Ids" content="j_id354:j_id355:0:1::j_id358,j_id354:j_id355:0:1::j_id358:childs,j_id354:j_id355:script" /><span id="ajax-view-state"><input type="hidden" name="javax.faces.ViewState" id="javax.faces.ViewState" value="j_id3" /></span><meta id="Ajax-Response" name="Ajax-Response" content="true" /></body></html>As you can see too much HTML code has been sent for not much of a visual change.
A more severe performance penalty:
- Open the Extended Data Table Demo
- On "State Name" paste "Alaska" (paste the name from clipboard), one row is shown
- Paste "Alabama" replacing "Alaska" (again paste from clipboard selecting Alaska first), again one different row is shown.
The answer (HTML code) is too big to put here, 3.474 bytes, if you inspect the result you will see a complete rewrite of the table including header.
IceFaces
- Open the Calendar demo
- Click on any different day
Something like this is the last AJAX response:
The answer (XML with metadata) is really big, 6.452 bytes, for a simple day change according to visual changes.
MyFaces/Trinidad
- Open this Tree Table Demo
- Expand node_0_0
- Expand node_0_0_0 (node node_0_0_0_ is shown)
- Collapse node_0_0_0 (hides/removes node_0_0_0_0)
The last AJAX response is too big to put here, 18.765 bytes, because is a complete rewrite of the tree component.
Update: a live demo of ADF Faces components is here and they seem to work fine as expected, that is, the ratio between code sent to the client and visual change is "correct" (in spite of HTML layout is very verbose the code sent to the client is almost the same to be displayed).
OpenFaces
- Open the Tree Table demo
- Expand "Re: Scalling an image"
- Expand the new child "Re: Scalling an image"
The last AJAX response is
<?xml version="1.0" encoding="UTF-8"?><ajaxResponse><head> </head><updatable id="subRows:2" type="portion" value="<tr><td><table cellspacing="0" cellpadding="0" class="o_cellWrapper"><tr><td class="o_treetable_indent"><div class="o_treetable_indent"></div></td><td class="o_treetable_indent"><div class="o_treetable_indent"></div></td><td class="o_treetable_indent"><div class="o_treetable_indent"></div></td><td class="o_treetable_indent"><div class="o_treetable_indent"></div></td><td><span class="treeTableText">Re: Scaling an image</span></td></tr></table></td><td><span class="treeTableText">Christian Smile</span></td><td><span class="treeTableText">Aug 3, 2007</span></td></tr>" data="{"structureMap":{"0":"1"}}" scripts="<script>O$.updateViewId('j_id3:j_id6');</script>" /></ajaxResponse>This code is very reasonable according to the change (a new child node/table row).
Nevertheless some component miserably fails:
- Open the Data Table demo
- Select "AK" as "State", resulting one row.
- Replace with "AR", resulting again a new row
The last AJAX result is too big, 38.209 bytes, because is a complete rewrite of the table including headers.
PrimeFaces
The AJAX answers of all tested examples were very reasonable. Said this, PrimeFaces lacks of a "filtered table component" or similar, the Achilles's heel of other JSF implementations.
Update: As Cagatay Civici (one of the fathers of PrimeFaces) points out, PrimeFaces has a filltered table, this component works fine regarding to the ratio of visual change/code sent to client (try to do the same tests as prvious frameworks).
Vaadin
This is the first non-JSF framework.
Open the Tree single selection demo
Select "Dell OptiPlex GX240"
Click "Apply" button (no change is needed)
This is the last AJAX answer:
for(;;);[{"changes":[["change",{"format": "uidl","pid": "PID190"},["12",{"id": "PID190","immediate":true,"caption": "Hardware Inventory","selectmode": "single","nullselect":true,"v":{"action":"","selected":["2"],"expand":[],"collapse":[],"newitem":[]}},["node",{"caption": "Desktops","key": "1","expanded":true,"al":["1","2"]},["leaf",{"caption": "Dell OptiPlex GX240","key": "2","selected":true,"al":["1","2"]}],["leaf",{"caption": "Dell OptiPlex GX260","key": "3","al":["1","2"]}],["leaf",{"caption": "Dell OptiPlex GX280","key": "4","al":["1","2"]}]],["node",{"caption": "Monitors","key": "5","expanded":true,"al":["1","2"]},["leaf",{"caption": "Benq T190HD","key": "6","al":["1","2"]}],["leaf",{"caption": "Benq T220HD","key": "7","al":["1","2"]}],["leaf",{"caption": "Benq T240HD","key": "8","al":["1","2"]}]],["node",{"caption": "Laptops","key": "9","expanded":true,"al":["1","2"]},["leaf",{"caption": "IBM ThinkPad T40","key": "10","al":["1","2"]}],["leaf",{"caption": "IBM ThinkPad T43","key": "11","al":["1","2"]}],["leaf",{"caption": "IBM ThinkPad T60","key": "12","al":["1","2"]}]],["actions",{},["action",{"caption": "Add child item","key": "1"}],["action",{"caption": "Delete","key": "2"}]]]]], "meta" : {}, "resources" : {}, "locales":[]}]It seems not very much, but if you review the code the entire tree is being rebuilt again.
ZK
Another non-JSF framework. In the last versions ZK embrace an hybrid approach, most of the visual logic is in client as JavaScript components, the server sends to the client high level commands to the high level client library (Vaadin is not different). I have not found a component sending too much code from client (according to the visual change) in ZK's demo.
ItsNat
The last framework studied, again a non-JSF framework.
In ItsNat the server keeps the same DOM state as in client and through DOM mutation events any change to the DOM in server automatically generates the JavaScript necessary to update the client accordingly.
- Open the demo
- Click on the handler of "Core" folder, the child nodes (11) are hidden.
Result code of the AJAX event:
itsNatDoc.addNodeCache(["cn_10","cn_14","0,1,1,0,0",["cn_15","cn_16"]]);
itsNatDoc.setAttribute2("cn_14","src","img/tree/tree_node_collapse.gif");
itsNatDoc.setAttribute2(["cn_15","cn_17","1"],"src","img/tree/tree_folder_close.gif");
itsNatDoc.setAttribute2(["cn_16","cn_18","1,0",["cn_19"]],"style","display:none");
itsNatDoc.setAttribute2(["cn_19","cn_20","1"],"style","display:none");
itsNatDoc.setAttribute2(["cn_19","cn_21","2"],"style","display:none");
itsNatDoc.setAttribute2(["cn_19","cn_22","3"],"style","display:none");
itsNatDoc.setAttribute2(["cn_19","cn_23","4"],"style","display:none");
itsNatDoc.setAttribute2(["cn_19","cn_24","5"],"style","display:none");
itsNatDoc.setAttribute2(["cn_19","cn_25","6"],"style","display:none");
itsNatDoc.setAttribute2(["cn_19","cn_26","7"],"style","display:none");
itsNatDoc.setAttribute2(["cn_19","cn_27","8"],"style","display:none");
itsNatDoc.setAttribute2(["cn_19","cn_28","9"],"style","display:none");
itsNatDoc.setAttribute2(["cn_19","cn_29","10"],"style","display:none");
No surprises.
Another test
Open this Tree demo
Click on "Insert Child". A new child node ("Actors") is inserted and a new log message is added.
AJAX result code:
itsNatDoc.removeAttribute2(["cn_15","cn_39","13"],"style");
itsNatDoc.setInnerHTML2("cn_39","<div><input> click</div><div>javax.swing.event.TreeModelEvent 13802934 path [Grey's Anatomy, Actors] indices [ 4 ] children [ Actors ]</div>");
var child = itsNatDoc.doc.createElement("li");
itsNatDoc.setAttribute(child,"style","padding:1px;");
itsNatDoc.appendChild2(["cn_17","cn_40","0,1,1,1",["cn_41","cn_42"]],child);
itsNatDoc.setInnerHTML(child,"<span><img src=\"img/tree/tree_node_expanded.gif\"><img src=\"img/tree/tree_folder_open.gif\"><span><b>Label</b></span></span>\n <ul style=\"list-style-type: none;\"></ul>\n ");
itsNatDoc.setTextData2(["cn_40","cn_43","4,0,2,0",["cn_44","cn_45"]],null,"Actors");
itsNatDoc.setAttribute2(["cn_45","cn_46","0"],"style","display:none");
itsNatDoc.setAttribute2(["cn_45","cn_47","1"],"src","img/tree/gear.gif");
Again no surprises.
And the Winner is...
There is no winner because only some components have been tested.
Having said this, apparently the only JSF implementation free of serious performance penalties is PrimeFaces.
In non-JSF frameworks using a very high level JS library like in Vaadin or ZK (PrimeFaces?) helps very much to reduce the network bandwidth (in spite of the fact that some components in Vaadin have serious performance problems), this cannot be said for client performance because in ItsNat the exact JS DOM code is sent to the client.
On the other side a high level JS library complicates custom component development (beyond composition) because the server does not help very much but this is another story, and another article.
- Login or register to post comments
- 11198 reads
- Printer-friendly version
(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)




Comments
Cagatay Civici replied on Tue, 2010/09/07 - 3:04pm
By filtered datatable in PrimeFaces, do you mean this?
http://www.primefaces.org/labs/ui/datatableFiltering.jsf
Jose Maria Arranz replied on Tue, 2010/09/07 - 4:54pm
in response to: cagataycivici
Thanks
and it works great.
Congratulations!
RIchard replied on Tue, 2010/09/07 - 5:40pm
Ronald Miura replied on Tue, 2010/09/07 - 6:12pm
It would be better to simplify your post and say 'I personally think that X is better than Y'.
(Although I'm pretty sure you're right in that *nothing* can beat JSF on being heavyweight)
Jose Maria Arranz replied on Wed, 2010/09/08 - 2:23am
in response to: ronaldtm
and post numbers on transferred bytes for only 4 of 8 frameworks tested, and yet, tries to draw conclusions from that?
Only posted numbers when the AJAX response is overwhelmingly big. Please read carefully all examples.
In the case of PrimeFaces, ZK and ItsNat I haven't found a component with bad ratio (in case of ItsNat I haven't searched very much because I'm the author).
John Waterwood replied on Wed, 2010/09/08 - 3:38am
Nice, but you repeatedly make the mistake of calling the JSF component libraries frameworks or even worse, JSF implementation.
Component libraries are neither, they simply are what their name implies: component libraries, which is really something else than a JSF implementation ;-)
Peter Karich replied on Wed, 2010/09/08 - 5:22am
Jose Maria Arraz, aeh, sorry. I have a lot of respect for your work and itsnat has a really nice idea for the programming model! But this article sucks! (sorry for being harsh) its the same BAD comparison you did on server side! Just Propaganda! I know that comparing web frameworks is hard but what you did is really stupid.
Are you really comparing different components?? (is this true?) this is not fair - its just a bad propaganda for your framework! Regarding the title: it is definitely not a comparison and definitely not a performance comparison!
So a big -1 for this article! (not for itsnat!)
Jose Maria Arranz replied on Wed, 2010/09/08 - 6:13am
in response to: peathal
Can you explain with professional arguments? (beyond easy and insulting rant)
Maybe do you feel angry because Wicket was discarded in TSS's slides?
Do you really think this kind of post is worth of a smart guy like you?
Why didn't you reply in TSS?
You can read 42 posts, most of them interesting and providing interesting reasons.
By the way, the original name of this article was "The Web Emperor has not Performance" (see the link of this page) it was changed by DZone's editors, anyway I agree with the title set by DZone, in spite of there are no side by side comparison between frameworks, COMPARISONS ARE UNAVOIDABLE... do yourself your own comparison.
Matthias Wessendorf replied on Wed, 2010/09/08 - 6:20am
I think I agree a bit with Peter, that this comparison is a very simple put. Size of the response is one thing, throughput etc is also not unimportant (in enterprise).Execution time of javascript etc. All missing :-)
Local stress tests would be also a good factor.
BTW. there is a live demo of ADF Faces (http://tinyurl.com/adf-faces-live)
The tree example can be reached here:
http://jdevadf.oracle.com/adf-richclient-demo/components/tree.jspx
open/close response is between 500 byte and 2000 (depends on content - what node you are working on)
Jose Maria Arranz replied on Wed, 2010/09/08 - 7:30am
in response to: mwessendorf
is also not unimportant
Rebuilding again and again a component after minor changes is not important?
Thanks for the link of ADF Faces, I've been trying some components (for instance the tree component) and I must to say they work fine as expected, that is, the ratio between code sent to the client and visual change is "correct" (in spite of HTML layout is very verbose = rich the code sent to the client is basically the same to be displayed).
Kenneth Mark replied on Wed, 2010/09/08 - 7:44am
Although I'm not fully agree with your test method (everyone got his own idea), I do
respect your work. From my daily working experience I also find Primefaces be better
than others mentioned JSF framework ( or components ).
Peter Karich replied on Wed, 2010/09/08 - 8:26am
Jose,
if my repsonse was too rude, sorry for this! And If the title was changed by dzone: ok. thats of course not your fault! (BTW: why not change it back?)
Performance comparisons should only be done with numbers. Where are they for PrimeFaces, Vaadin, ItsNat and ZK? Where is the table or the graph to get an impression of the actual difference?
And additionally in this case:
> in spite of the fact that some components in Vaadin have serious performance problems
this is not helpful for the developers nor for the readers already using Vaadin. and did you mean bandwidth or performance? you didn't measure the performance. neither on server nor on the client side, did you?
> Maybe do you feel angry
No, I don't feel angry :-) I am just irritated how you fairly compare things.
> Maybe do you feel angry because Wicket was discarded in TSS's slides?
No, I don't think so. I am NOT related or coupled to any framework - I am a developer who get things done: I like wicket, I like vaadin, I like Swing, I hate JSF, I like the idea of ItsNat, I dislike the license of ItsNat ;-) and so on. No framework is perfect.
> Why didn't you reply in TSS?
Sorry, my reply would have been far more negative than my previous one ;-)
Because: You have shown which frameworks exists (not all, but a lot according to wikipedia ;-)). And you probably are showing some minor pro here and some cons there, sometimes a bit confusing and subjective. But this was not a feature by feature comparison what I would expect from a smart guy like you :-)
You were bashing the whole work of developers from various frameworks - not only wicket!
My bad comments here are hopefully only bashing this post and the TSS slide - not you or your work with ItsNat!
> do yourself your own comparison.
that's true. always do your own comparisons! So, why the hell are we Java-bloggers/developers posting comparisons? ;-)
Jose Maria Arranz replied on Wed, 2010/09/08 - 8:23am
in response to: peathal
Peter, some month ago you wrote this article, an extremely superficial promotion/comparison (propaganda?) of Wicket vs everybody.
Said this, how can you say that TSS article/slides (98 slides plenty of arguments!!) and this article are "bad propaganda"? Are you kidding?
Do you understand what is the ratio between code sent to client/visual changes done (equivalent markup or JS DOM actions)?
I don't provide concrete numbers of this ratio (is hard to calculate) but everybody can see brutal differences between frameworks, if you can see differences you are COMPARING.
Regarding your loved Wicket
Enable the FireBug's Console
1) Open this tree demo
2) Expand the root node
3) Select the first child row
The AJAX result for a simple color change is:
Jose Maria Arranz replied on Wed, 2010/09/08 - 8:48am
Peter, there is NO SIDE BY SIDE comparison with exact numbers (the "ratio" number) because is a very time consuming task, point.
Said this, in some cases in spite of I don't have the exact number, the size of AJAX response regarding to the visual change is BRUTAL and anyone can see it. This is not the case of PrimeFaces, ZK and ADF Faces (and ItsNat), I haven't found JUST ONE component with a bad ratio, point, in case of Vaadin it may be just a bad designed component (I haven't studied the complete suite).
You were bashing the whole work of developers from various frameworks - not only wicket!
I'm not bashing anybody, I just talking about technology, as you can see in this article and ANY article of mine, the words "stupid" and "sucks" are not in my mouth.
that's true. always do your own comparisons! So, why the hell are we Java-bloggers/developers posting comparisons? ;-)
You are the first doing (superficial) comparisons like your cited article. JavaLobby (DZone in general), TSS etc etc are plenty of comparisons and opinions, every day, every article, every post, most of them are not so founded, polite, fair and balanced like this article.
Peter Karich replied on Wed, 2010/09/08 - 2:24pm
> Peter, some month ago you wrote this article, an extremely superficial promotion/comparison (propaganda?) of Wicket vs everybody.
This was propaganda, of course. As the title should have suggested:
Not A Java Web Frameworks Survey: Just use Wicket!
All readers should notice that this is NOT a comparison!
BTW: I think, if you won't call your posts 'comparison' I would be fine.Dean Pehrsson-c... replied on Wed, 2010/09/08 - 9:16am
Henk De Boer replied on Wed, 2010/09/08 - 4:29pm
in response to: Powerjohn
You are right, but since many of the (old) 1.2 component libraries were actually a kind of mini-framework of themselves (on top of the core JSF implementation), it's maybe understandable that some started to call them frameworks.
With JSF 2.0 this should all be much better and the component libraries can hopefully focus more on that which they indeed are: component libraries ;)
Calling a component a JSF implementation is pretty wrong indeed. There are only two JSF implementations, MyFaces Core and Mojarra (Sun/Oracle JSF RI).
Jose Maria Arranz replied on Thu, 2010/09/09 - 2:05am
in response to: henk
Yes you are right if we think "very strictly" but these component libraries are tightly coupled and based on a common foundation, we are not talking about isolated components put together on top of MyFaces or Mojarra, in summary is hard to differentiate these component collections from "frameworks", and mind share names them "frameworks".
Henk De Boer replied on Thu, 2010/09/09 - 4:08pm
in response to: jmarranz
Things that are truly components can interact with each other. I can put a t:panelGroup inside a rich:dataTable together with an o:spinner. These can all interact with each other, since the component model is standardized.
Therefor, Tomahawk, RichFaces and OpenFaces are components for JSF.
However, I can't mix and match components from Wicket and JSF together with tags from Struts on a single page.
Therefor, Wicket, JSF and Struts are frameworks.
Oleg Varaksin replied on Thu, 2010/10/28 - 10:25am