Search code examples
actionscript-3apache-flexflex4lazy-loadingflex4.5

Flex tree expand slowly/lazy loading when there are more than 30000 nodes


I want to open all nodes of Flex mx Tree in such a way that UI is responsive at all times. Normally when there are limited no of nodes then this code works just fine.

public function expandAllNodes():void {
  for (var i:int = 0; i < this.dataProvider.length; i++) {
    expandChildrenOf(this.dataProvider.getItemAt(i), true);
  }
}

maybe i need to callLater instead of directly calling the function

public function expandAllNodes():void {
  for (var i:int = 0; i < this.dataProvider.length; i++) {
    calllater(expandChildrenOf,[this.dataProvider.getItemAt(i), true]);
  }
}

but this is not working either.


Solution

  • Using callLater won't help in this case. From the documentation,

    The callLater method queues an operation to be performed for the next screen refresh, rather than in the current update.

    Using callLater in your loop will simply push all the expandChildrenOf() calls to the next screen refresh -- which will still put way too much work into a single update cycle.

    Instead, you could spread your loop over several frames and limit work done per frame:

    private var processingLimit:int = 10; //experiment to get a reasonable value for this
    private var totalNodes:int = 0;
    private var nodesProcessed:int = 0;
    
    public function expandAllNodes():void {
        this.totalNodes = this.dataProvider.length;
        this.addEventListener(Event.ENTER_FRAME, expandNextNode);
    }
    
    private function expandNextNode(e:Event):void {
        var numToProcess = Math.min(processingLimit + nodesProcessed, totalNodes);
        for (var i:int = nodesProcessed; i < numToProcess; i++) {
            nodesProcessed++;
            expandChildrenOf(this.dataProvider.getItemAt(i), true);
        }
    
        if (numToProcess == totalNodes) {
            this.removeEventListener(Event.ENTER_FRAME, expandNextNode);
        }
    }
    

    n.b. Make sure that expandChildrenOf doesn't recursively open children of children -- if it does, then you could still end up expanding the entire tree based on a single call to expandChildrenOf(1);!