Hi Ulrich,
(Moving discussion to dev_at_javaserverfaces.java.net)
Thank you for taking the time to look at this. We really appreciate your
comments and we will have a look at this with the suggested changes in
mind. As you are probably aware this part is very tricky.
Note if you want to discuss it in a more real time manner we are on the
#mojarra channel on irc.freenode.net
Thanks again!
Manfred
On 4/3/14, 10:36 AM, ulrich_at_optimal-systems.de wrote:
> Hi,
>
> I subscribed to this Mailing list because M. Riem asked me to propse
> any suggestions for improving performance in
> FaceletViewHandlingStrategy.buildView() which relate to re-applying
> dynamic adds, see issue in subject.
> Since the issue has been closed, I guess I have to participate via some
> mailing list.
> Maybe this is the wrong one.
>
> Nevertheless:
> As Manfred indicates in his comment on the issue, one canot completly
> suppress re-applying the dynamic adds because of transient components.
> I have to admit that I do not understand these Problems in detail.
>
> But I have another suggestions:
>
> Fist, locateComponentByClientId() of FaceletViewHandlingStrategy is
> slow, because it always starts to search at UIViewRoot. Issue 2876
> addresses the Problem. It even states that the improvement is fixed in
> 2.1.23. But at least according to the source code I downloaded via
> maven for 2.1.28 that is not true.
>
>
> Also, I tried to speed things up by changing
> reapplyDynamicAdd(FacesContext , ComponentStruct) .
>
> For one thing, if children are added dynamically to a parent, one often
> adds multiple children to that parent.One can cache the parents in a
> Map which is created in reapplyDynamicActions(FacesContext), and put a
> parent into that Map if it has been located once. When another
> ComponentStruct refers to the same parent, it can be read from that Map
> instead of performing locateComponentByClientId() again.
>
> Also, if the child can be located (because it has already been added in
> RESTORE_VIEW), I checked if there are any transient siblings. I guess
> if there are no transient siblings, there can be no conflicts with a
> mixture of transient components and dynamically added coponents in that
> parent. Also, I guess there can be no Problems if the dynamically added
> component is a facet.
>
> Here is a code snippet with my changes (excluding the refactoring of
> locateComponentByClientId() and reapplyDynamicActions():
>
> private void reapplyDynamicAdd(FacesContext context,
> ComponentStruct struct,
> Map<String,
> UIComponent> parents,
>
> Set<UIComponent> parentsWithoutTransientChildren) {
>
> UIComponent parent = parents.get(struct.parentClientId);
> if (parent == null)
> {
> parent = locateComponentByClientId(context,
> struct.parentClientId, context.getViewRoot());
> if (parent != null)
> {
> parents.put(struct.parentClientId, parent);
> }
> }
>
> if (parent != null) {
> UIComponent child = locateComponentByClientId(context,
> struct.clientId, parent);
> StateContext stateContext =
> StateContext.getStateContext(context);
>
> if (child == null) {
> child =
> stateContext.getDynamicComponents().get(struct.clientId);
> }
> else {
>
> if (struct.facetName == null) {
> if
> (parentsWithoutTransientChildren.contains(parent)) {
> return;
> }
>
> boolean anyTransient = false;
> for(UIComponent sibling : parent.getChildren())
> {
> if (sibling.isTransient()) {
> anyTransient = true;
> break;
> }
> }
>
> if (anyTransient == false) {
>
> parentsWithoutTransientChildren.add(parent);
> return;
> }
> }
> else {
> return;
> }
> }
> // the remaing code of the method has not been changed
>
>
> That change improves performance in about the same degree as my
> previous Suggestion (which was refused by Manfred).