We are developing an enterprise application with pretty large and complex views based on Mojarra 2.2.8. Our largest views produce JSF component trees of >20.000 nodes. Of coure we ran into performance issues, so we started to reduce the tree size by replacing <ui:repeat>
with <c:forEach>
and by replacing the rendered
attribute with <c:if>
blocks as recommended in this very informative post by BalusC.
These measures reduced the component tree by a huge amount and brought significant improvements in performance.
One measure did not work out though: Our views contain severals tabs in a tab group. When we tried to remove contents of invisible tabs via <c:if>
tags, the component tree of these tabs was still present and there was no benefit in performance.
We figured out, that the only difference between this usage of <c:if>
and several other places was, that this time <c:if>
was part of a composite component and its contents were injected through a <composite:insertChildren/>
tag. The process of injecting the children of a composite component tag to its definition seems to somehow conflict with the <c:if>
tag. We also tried to replace the insertChildren
tag with a facet
based approach, but the result remained the same.
To demonstrate this, here is a composite component, that wraps all its contents in a <c:if>
tag, that always evaluates to false
:
<composite:interface>
</composite:interface>
<composite:implementation>
<c:if test="false">
<composite:insertChildren />
</c:if>
</composite:implementation>
This component shoud display nothing, even if it is used with a lot of child elements in a view. And it does display nothing but the component tree is still there and there is no performance benefit.
Unfortunately, this makes it impossible for us, to develop a performance optimized tab group composite component. Can anybody please explain, why this happens and if there is a way around it?
We are on mojarra 2.2.8, el-api 2.2.5, tomcat 8.0.