How to improve performance of populating a massive tree view?

If you really care about speed of populating a massive treeview, you should look into virtualTreeView (http://code.google.com/p/virtual-treeview/).
It's an open source treeview specifically designed to be virtual and maximize speed/memory for large treeviews.
It's an amazing component.


There is a common trick in tree views to improve the performance in this type of situation. When you refresh this tree view, only load the first level of hierarchy, and don't worry about any further levels. Instead, you can load each additional level at the time of expanding each node. Here's how to do it.

When you populate the first level, rather than continuing with loading each of its child nodes, instead just create 1 "dummy" child node with a nil pointer in its Data property - since each node is expected to have an object in the Data property anyway. Then, monitor the OnExpanding event of the tree view. When a node is expanded, it will check to see if this "dummy" child node exists or not. If so, then it knows it needs to load the child nodes.

When the first level of hierarchy is loaded...

var
  X: Integer;
  N, N2: TTreeNode;
  O: TMyObject;
begin
  for X := 0 to MyObjectList.Count - 1 do begin
    O:= TMyObject(MyObjectList[X]); //Object which Node represents
    N:= TreeView.Items.AddChild(nil, O.Caption);
    N.Data:= O;
    N2:= TreeView.Items.AddChild(N, '');
    N2.Data:= nil; //To emphasize that there is no object on this node
  end;
end;

Then, create an event handler for OnExpanding...

procedure TForm1.TreeViewExpanding(Sender: TObject; Node: TTreeNode;
  var AllowExpansion: Boolean);
var
  N: TTreeNode;
begin
  N:= Node.getFirstChild;
  if N.Data = nil then begin
    //Now we know this is a "dummy" node and needs to be populated with child nodes
    N.Delete; //Delete this dummy node
    LoadNextLevel(N); //Populates child nodes by iterating through master list
  end;
end;

The only disadvantage to this trick is that all nodes which have not yet been expanded will have a + next to them, even though there may not be any child nodes. If this is the case, then when the user clicks the + to expand a node, the child node gets deleted and the + disappears so the user knows there are no child nodes within that node.

Also, using BeginUpdate and EndUpdate in TreeView.Items improves performance by not performing GUI updates until it's all done...

TreeView.Items.BeginUpdate;
try
  //Refresh the tree
finally
  TreeView.Items.EndUpdate;
end;