[
https://jira.jboss.org/jira/browse/JBSEAM-3008?page=com.atlassian.jira.pl...
]
Sebastian Hennebrueder commented on JBSEAM-3008:
------------------------------------------------
// copy of the post to the dev list
Hello,
far away from being a guru of anything but I looked through the code.
Related to thie JBSEAM-3008 and the posting on
http://seamframework.org/Documentation/TuningTheSeamWebsite
I evaluted JSF reference implementation 1.2.04
A component extending from UIComponentBase has a number of JSF phase handler.
processRestoreState
processDecodes
processValidators
processUpdates
processSaveState
a get request is only calling processSaveState but a post request is calling everything
The implementations are more or less iterating through the childs and calling the child
handlers
Three methods (
processDecodes
processValidators
processUpdates
) are calling isRendered which in turn leads to an EL resolution.
In totally isRendered is called at least 5 times before an element is rendered. Calls are
not cached and the EL is evaluated every time.
Calling methods are encodeChild,encodeBegin/encodeEnd/encodeChildren and a super class + 3
if the request is a post and the component extends UIComponentBase
There are two consequences: one for a proper cache implementation and one for performance
1) cache
To have a proper cache implementation our cache component needs to overwrite at least
phase listener
processDecodes
processValidators
processUpdates
with an empty implementation. This will block all following updates as JSF is always
running through the object tree. As a consequence the cached fragment should not be a
form. The content will not be updated, even if it is not yet cached. processSaveState and
processRestoreState should not be overwritten. It might be slightly inefficient but these
methods fill the component tree we need to cache.
Actually, I wanted to create a patch but where is the source for HtmlCache. It seams not
to be in seam-trunk. Anyway, just overwrite the three methods and don't delegate to
the parent class but leave it empty.
2) performance
This is not related to the cache but a general JSF problem.
In the class org.jboss.seam.ui.util.cdk.RendererBase add two lines to evaluate the
rendered expression
and call setRendered and set the result of the evaluation. This will reduce the calls for
all components using this renderer to one call.
It would reduce the rendered EL calls by 80 % . The question is, if we will see any side
effects. If no components are doing funny things, it should work. I would propose that we
carefully test this in different applications.
public void renderChildren(FacesContext facesContext, UIComponent component) throws
IOException {
if (component.getChildCount() > 0) {
for (Iterator it = component.getChildren().iterator(); it.hasNext();) {
UIComponent child = (UIComponent) it.next();
// here the two lines
boolean rendered = child.isRendered();
child.setRendered(rendered);
renderChild(facesContext, child);
}
}
Best Regards
Sebastian Hennebrueder
----
www.laliluna.de
Training, Tutorials and Java Development
Page fragment caching impossible with coarse-grained rendered
attribute evaluation in JSF
-----------------------------------------------------------------------------------------
Key: JBSEAM-3008
URL:
https://jira.jboss.org/jira/browse/JBSEAM-3008
Project: Seam
Issue Type: Task
Components: JSF Controls, JSF Integration
Reporter: Christian Bauer
The evaluation of the JSF rendered="true|false" attribute conflicts with the
Seam page fragment cache.
<s:cache region="test" key="foo123">
<h:outputText value="FOO" rendered="#{foo.bar}"/>
</s:cache>
The rendered attribute of the child components is ALWAYS evaluated, in potentially any
JSF phase (especially APPLY REQUEST VALUES and RENDER RESPONSE of course). No switch or
combination of JSF component settings and renderers is able to stop that evaluation; you
can not say "Do not call isRendered() on any child component of
<s:cache>".
So any rendered-attribute expression that is costly (e.g. rendered="#{not empty
myBackingBean.resultList}") will not be cached. This also means that there is a
disconnect between what is finally rendered by s:cache (some HTML from the cache) and what
the evaluation of the rendered attribute might produce. This is extremely difficult to
work around. One approach is to only use lightweight rendered="#{foo}"
expressions that can be evaluated many times without much cost.
I don't see any way to fix this unless the JSF specification is changed and a more
sane model of rendering/non-rendering switches is introduced. The rendered attribute is
used for all kinds of purposes inside the JSF engine, most of them have nothing to do with
rendering (e.g. it is used in APPLY REQUEST VALUES to detect which bindings need to be
evaluated back onto the model).
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
https://jira.jboss.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
http://www.atlassian.com/software/jira