0 Replies Latest reply on May 22, 2012 4:15 AM by Alex Vb

    Richfaces tree is walked multiple times during request

    Alex Vb Newbie

      I'm using a rich:tree component which contains quite a few nodes (and the amount of nodes will only ever increase). The usecase is pretty simple: the tree represents (sort of) a file system where you can select items. If you select an item, a "render" occurs of another panelGroup somewhere which contains the properties & content of the item you selected. However the web interface is rather slow, it takes 1-2 seconds for a page to render so I enabled some logging. Turns out the entire tree is "walked" 4 times for each request, each time taking about 300-500ms.

       

      I created a small test project where you can see this output:

       

      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

       

      I'm using toggleType="client" but I noticed if you switch to "ajax" only the "expanded" part of the tree is walked. However the ajax toggleType is too slow for our usecase and it still does not solve the fundamental problem.

       

      I did some digging in the richfaces sourcecode (mind you that I am new to JSF so I could be way off) and I noticed that a lot of methods in UIDataAdapter (processDecodesChildren, processValidatesChildren, processUpdatesChildren) perform an "iterate()" which in turn performs a walk() which is implemented in AbstractTree to use the TreeRange to determine which nodes should be walked.

       

      As far as I can see the entire tree is walked with a TreeDataVisitor, presumably to update/check for updates/... However in my usecase the tree is very static. Am I doing something wrong or is there a way to turn off the iteration?

      I think I could set selectionType to "client" (though the selectionChangeListener is no longer invoked then) and use javascript to submit the selected id via another form or without a form alltogether?

       

      Is my usecase different from the intended one for the rich:tree? If so, is there a way to support both?