[ 
https://issues.jboss.org/browse/RF-12281?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12738500#comment-12738500
 ] 

Lukáš Fryč commented on RF-12281:
---------------------------------

Hey Alex,

I have created sample with 2-level deep tree, once I select a root node - level 
0 using zero-based counting, then I get:

{code}
15:32:40,181 INFO  [stdout] (http--0.0.0.0-8080-4) Before RESTORE_VIEW 1
15:32:40,185 INFO  [stdout] (http--0.0.0.0-8080-4) After RESTORE_VIEW 1
15:32:40,186 INFO  [stdout] (http--0.0.0.0-8080-4) Before APPLY_REQUEST_VALUES 2
15:32:40,197 INFO  [stdout] (http--0.0.0.0-8080-4) Inside Selection Change 
Action
15:32:40,198 INFO  [stdout] (http--0.0.0.0-8080-4) After APPLY_REQUEST_VALUES 2
15:32:40,198 INFO  [stdout] (http--0.0.0.0-8080-4) Before PROCESS_VALIDATIONS 3
15:32:40,206 INFO  [stdout] (http--0.0.0.0-8080-4) After PROCESS_VALIDATIONS 3
15:32:40,206 INFO  [stdout] (http--0.0.0.0-8080-4) Before UPDATE_MODEL_VALUES 4
15:32:40,215 INFO  [stdout] (http--0.0.0.0-8080-4) After UPDATE_MODEL_VALUES 4
15:32:40,215 INFO  [stdout] (http--0.0.0.0-8080-4) Before INVOKE_APPLICATION 5
15:32:40,215 INFO  [stdout] (http--0.0.0.0-8080-4) After INVOKE_APPLICATION 5
15:32:40,215 INFO  [stdout] (http--0.0.0.0-8080-4) Before RENDER_RESPONSE 6
15:32:40,226 INFO  [stdout] (http--0.0.0.0-8080-4) After RENDER_RESPONSE 6
{code}

When I select an inner node on level 1:

{code}
15:35:13,702 INFO  [stdout] (http--0.0.0.0-8080-4) Before RESTORE_VIEW 1
15:35:13,707 INFO  [stdout] (http--0.0.0.0-8080-4) After RESTORE_VIEW 1
15:35:13,708 INFO  [stdout] (http--0.0.0.0-8080-4) Before APPLY_REQUEST_VALUES 2
15:35:13,725 INFO  [stdout] (http--0.0.0.0-8080-4) getChildAt(0)
15:35:13,725 INFO  [stdout] (http--0.0.0.0-8080-4) Inside Selection Change 
Action
15:35:13,726 INFO  [stdout] (http--0.0.0.0-8080-4) After APPLY_REQUEST_VALUES 2
15:35:13,726 INFO  [stdout] (http--0.0.0.0-8080-4) Before PROCESS_VALIDATIONS 3
15:35:13,734 INFO  [stdout] (http--0.0.0.0-8080-4) After PROCESS_VALIDATIONS 3
15:35:13,735 INFO  [stdout] (http--0.0.0.0-8080-4) Before UPDATE_MODEL_VALUES 4
15:35:13,743 INFO  [stdout] (http--0.0.0.0-8080-4) After UPDATE_MODEL_VALUES 4
15:35:13,744 INFO  [stdout] (http--0.0.0.0-8080-4) Before INVOKE_APPLICATION 5
15:35:13,744 INFO  [stdout] (http--0.0.0.0-8080-4) After INVOKE_APPLICATION 5
15:35:13,744 INFO  [stdout] (http--0.0.0.0-8080-4) Before RENDER_RESPONSE 6
15:35:13,746 INFO  [stdout] (http--0.0.0.0-8080-4) getChildAt(0)
15:35:13,754 INFO  [stdout] (http--0.0.0.0-8080-4) After RENDER_RESPONSE 6
{code}

When I select leaf on level 2:

{code}
15:35:49,321 INFO  [stdout] (http--0.0.0.0-8080-4) Before RESTORE_VIEW 1
15:35:49,327 INFO  [stdout] (http--0.0.0.0-8080-4) After RESTORE_VIEW 1
15:35:49,328 INFO  [stdout] (http--0.0.0.0-8080-4) Before APPLY_REQUEST_VALUES 2
15:35:49,341 INFO  [stdout] (http--0.0.0.0-8080-4) getChildAt(0)
15:35:49,341 INFO  [stdout] (http--0.0.0.0-8080-4) getChildAt(0)
15:35:49,341 INFO  [stdout] (http--0.0.0.0-8080-4) Inside Selection Change 
Action
15:35:49,342 INFO  [stdout] (http--0.0.0.0-8080-4) After APPLY_REQUEST_VALUES 2
15:35:49,342 INFO  [stdout] (http--0.0.0.0-8080-4) Before PROCESS_VALIDATIONS 3
15:35:49,350 INFO  [stdout] (http--0.0.0.0-8080-4) After PROCESS_VALIDATIONS 3
15:35:49,350 INFO  [stdout] (http--0.0.0.0-8080-4) Before UPDATE_MODEL_VALUES 4
15:35:49,357 INFO  [stdout] (http--0.0.0.0-8080-4) After UPDATE_MODEL_VALUES 4
15:35:49,357 INFO  [stdout] (http--0.0.0.0-8080-4) Before INVOKE_APPLICATION 5
15:35:49,357 INFO  [stdout] (http--0.0.0.0-8080-4) After INVOKE_APPLICATION 5
15:35:49,357 INFO  [stdout] (http--0.0.0.0-8080-4) Before RENDER_RESPONSE 6
15:35:49,359 INFO  [stdout] (http--0.0.0.0-8080-4) getChildAt(0)
15:35:49,360 INFO  [stdout] (http--0.0.0.0-8080-4) getChildAt(0)
15:35:49,368 INFO  [stdout] (http--0.0.0.0-8080-4) After RENDER_RESPONSE 6
{code}

There is really nothing avoidable in calling {{getChildAt}}.
For each level excluding root the {{getChildAt}} method is called at most once 
per phase.

The general recommendation is making {{getChildAt}} cached during whole request 
(e.g. using request scoped bean state). Then, first phase will may be more 
demanding, but other phases will be fast.
                
> rich:tree is iterated multiple times when item is selected
> ----------------------------------------------------------
>
>                 Key: RF-12281
>                 URL: https://issues.jboss.org/browse/RF-12281
>             Project: RichFaces
>          Issue Type: Bug
>      Security Level: Public(Everyone can see) 
>          Components: component-tree
>    Affects Versions: 4.2.2.Final
>            Reporter: Alex Vb
>            Assignee: Lukáš Fryč
>             Fix For: 4.3.0.M3
>
>
> I have a decently sized tree and I'm using the selectionChangeListener in 
> combination with toggleType="client" selectionType="ajax" render="node" to 
> trigger a selection event on the server. The panelGroup "node" is re-rendered 
> afterwards but it takes 1-2 seconds for each request. After enabling some 
> debug logging I noticed that the entire tree is iterated 4 times for each 
> request. Note a small test-tree exhibiting the same behavior:
> {code}
> 2012-05-22 08:39:29.287 DEBUG CustomPhaseListener - Before phase: 
> APPLY_REQUEST_VALUES 2
> 2012-05-22 08:39:29.287 DEBUG TreeNodeBase - getChildrenKeysIterator(0)
> 2012-05-22 08:39:29.287 DEBUG TreeNodeBase - getChild(1)
> 2012-05-22 08:39:29.287 DEBUG TreeNodeBase - getChildrenKeysIterator(1)
> 2012-05-22 08:39:29.287 DEBUG TreeNodeBase - getChild(2)
> 2012-05-22 08:39:29.287 DEBUG TreeNodeBase - getChild(2)
> 2012-05-22 08:39:29.287 DEBUG TreeNodeBase - getChild(2)
> 2012-05-22 08:39:29.287 DEBUG Bean - selectionChanged()
> 2012-05-22 08:39:29.287 DEBUG CustomPhaseListener - After phase: 
> APPLY_REQUEST_VALUES 2
> 2012-05-22 08:39:29.287 DEBUG CustomPhaseListener - Before phase: 
> PROCESS_VALIDATIONS 3
> 2012-05-22 08:39:29.287 DEBUG TreeNodeBase - getChildrenKeysIterator(0)
> 2012-05-22 08:39:29.287 DEBUG TreeNodeBase - getChild(1)
> 2012-05-22 08:39:29.287 DEBUG TreeNodeBase - getChildrenKeysIterator(1)
> 2012-05-22 08:39:29.287 DEBUG TreeNodeBase - getChild(2)
> 2012-05-22 08:39:29.302 DEBUG TreeNodeBase - getChild(2)
> 2012-05-22 08:39:29.302 DEBUG CustomPhaseListener - After phase: 
> PROCESS_VALIDATIONS 3
> 2012-05-22 08:39:29.302 DEBUG CustomPhaseListener - Before phase: 
> UPDATE_MODEL_VALUES 4
> 2012-05-22 08:39:29.302 DEBUG TreeNodeBase - getChildrenKeysIterator(0)
> 2012-05-22 08:39:29.302 DEBUG TreeNodeBase - getChild(1)
> 2012-05-22 08:39:29.302 DEBUG TreeNodeBase - getChildrenKeysIterator(1)
> 2012-05-22 08:39:29.302 DEBUG TreeNodeBase - getChild(2)
> 2012-05-22 08:39:29.302 DEBUG TreeNodeBase - getChild(2)
> 2012-05-22 08:39:29.302 DEBUG CustomPhaseListener - After phase: 
> UPDATE_MODEL_VALUES 4
> 2012-05-22 08:39:29.302 DEBUG CustomPhaseListener - Before phase: 
> INVOKE_APPLICATION 5
> 2012-05-22 08:39:29.302 DEBUG CustomPhaseListener - After phase: 
> INVOKE_APPLICATION 5
> 2012-05-22 08:39:29.302 DEBUG CustomPhaseListener - Before phase: 
> RENDER_RESPONSE 6
> 2012-05-22 08:39:29.302 DEBUG TreeNodeBase - getChild(2)
> 2012-05-22 08:39:29.318 DEBUG TreeNodeBase - getChildrenKeysIterator(0)
> 2012-05-22 08:39:29.318 DEBUG TreeNodeBase - getChild(1)
> 2012-05-22 08:39:29.318 DEBUG TreeNodeBase - getChildrenKeysIterator(1)
> 2012-05-22 08:39:29.318 DEBUG TreeNodeBase - getChild(2)
> 2012-05-22 08:39:29.318 DEBUG TreeNodeBase - getChild(2)
> 2012-05-22 08:39:29.318 DEBUG CustomPhaseListener - After phase: 
> RENDER_RESPONSE 6
> {code}
> On the rather large tree each iteration takes 300-500 ms which explains the 
> slow behavior. I have played around with every setting I could find, if 
> selectionType is set to "client" the tree is iterated only once (during the 
> render response phase) but the selection event does not seem to be triggered. 
> If toggleType is set to ajax, only the "expanded" parts of the tree are 
> iterated.
> I have no idea why the iteration is necessary for all these phases but I 
> "fixed" it in my implementation by recompiling the 
> org.richfaces.component.TreeRange class with an updated method:
> {code:java}
>     public boolean shouldIterateChildren() {
>       if (tree.isLeaf())
>               return false;
>       else {
>               char separatorChar = 
> UINamingContainer.getSeparatorChar(FacesContext.getCurrentInstance());
>               String clientId = tree.getClientId();
>               boolean render = false;
>               for (String idToRender : 
> FacesContext.getCurrentInstance().getPartialViewContext().getRenderIds()) {
>                       // render the tree if you explicitly mention either the 
> client id (e.g. "menuForm:tree") or the parent component client id (e.g. 
> "menuForm")
>                       // note that when clicking on an object in the tree, 
> the following render target is requested: menuForm:tree@selection
>                       if (clientId.equals(idToRender) || 
> clientId.matches(idToRender + separatorChar + ".*")) {
>                               render = true;
>                               break;
>                       }
>               }
>               // always render if it's not a postback
>               return render || 
> !FacesContext.getCurrentInstance().isPostback();
>           }
>     }
> {code}

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira

_______________________________________________
richfaces-issues mailing list
[email protected]
https://lists.jboss.org/mailman/listinfo/richfaces-issues

Reply via email to