Open SCLDGit opened 3 years ago
The built-in treeview is not virtualized. There is an example of a manual treeview implementation on top of ItemsRepeater here https://github.com/kekekeks/example-avalonia-huge-tree
Are there any plans to add virtualization to the TreeView? I'll check out your example in the meantime.
Probably not - virtualizing lists with variable height items is fraught with problems, and TreeView
is an extreme example of this.
I am considering adding a TreeList
control at some point though, which would work similarly to @kekekeks's example. No promises on timeline though.
Any updates over time would be much appreciated. As is, without some additional guidance on potential workarounds, we're more or less dead in the water in terms of migrating our app to Avalonia. The tree is a big part of our workflow and our customers routinely have 5-10k root level items plus many more in the hierarchy below the root as part of their workflows.
5-10k root level items plus many more in the hierarchy below the root as part of their workflows.
It's almost never necessary to load that many items in a TreeView at once. I suggest you implement your own form of "virtualizing" which is basically do not add children of collapsed nodes to the TreeView. When a node is expanded, dynamically load it's chiildren.
That is what file explorers and other similar apps do where it is impossible for performance reasons to load the entire file system at once in the TreeView.
That's a big ask of users coming from WPF where tree virtualization is built into the control (and it really screws with MVVM). Loading children only at expansion is not an option in our case for various technical reasons to do with our customers' various workflows, and regardless doesn't address the situation where customers have large numbers of items that aren't nested at all.
@SCLDGit Can you provide examples? I have never seen a case where so many items need to be loaded at once in a TreeView. Perhaps 3D/graphics software only? The TreeView design itself is intentionally designed to expand/collapse large sets with hierarchy so not all is visible at the same time. DataGrid is when everything needs to always be visible (you can even show hierarchy and expand/collapse groups with a few tricks).
I understand it isn't MVVM friendly at first, you will have to create a subset view model of your huge view model (it can be done). Many optimizations aren't MVVM friendly. In large production apps it's common not to fully follow MVVM in the theoretical sense for exactly these reasons. Performance is more important than beautiful MVVM code. MVVM actually holds you back in some cases with it's change propagation and binding requirements (Avalonia less so than others).
That said, the WinUI TreeView has never been stable (and isn't useful for production) and I've never seen anything but issues in the edge cases with ItemsRepeater. It might be better to re-base Avalonia on the WPF source code now for TreeView.
Our users use the tree as a visual representation of their network infrastructure, they can group (or not) into hierarchies as they please. Most of our users manage 1000+ endpoints with our software, some as many as 20k, and the tree operates as a multi-functional center point for all endpoint interaction (e.g. checking checkboxes at group or individual levels to add items to a task, selecting groups and/or individual nodes for generating reports, etc.). The ability to (potentially) view the entire tree at once (with scrolling, of course) is vital to the operation of the system.
@SCLDGit is this for a commercial application? Would you be willing to pay for a commercial control for this? If so we might have a solution.
@grokys
@SCLDGit is this for a commercial application? Would you be willing to pay for a commercial control for this? If so we might have a solution.
Yes, this is for a commercial application. We currently have DevExpress controls licensed. For the right price, we'd certainly be willing to pay for Avalonia controls that could get us transitioned to a cross-platform application in the near future.
@SCLDGit if you'd like to drop us an email at team@avaloniaui.net we can have a chat.
@SCLDGit Can you provide examples? I have never seen a case where so many items need to be loaded at once in a TreeView. Perhaps 3D/graphics software only?
Something like AST or parse tree exploring. For instance, https://astexplorer.net/ but offline.
We are encountering the same issue in our CAD software as we load thousands of objects and the treeitems have several SVG icons it lacks heavily:
Any solution planned for this ?
@markusalbrecht-procam please try TreeDataGrid
@maxkatz6 we will use this as the last option as we already rewrote from listitems to treeview - the result is now better but not optimal as we use a lot svgs inside the tree for all items that seems to be the problem. Without images it works fine.
@markusalbrecht-procam you can try lazy loading also
@timunie In fact if the treeviewitems are not expanded the images are not loaded so that works from scratch no lazy loading needed - performance is good. The problem is when Nodes are already expanded (as we implemented the IsExpanded state lately) and then reload the tree - what happens when we switch between different documents - then it also needs to load all the images of the expanded.
🤔 For images I use in several places I use some kind of ImageCache where I can reuse an existing one. But that only solves the I/O operation needed, still you have a lot of items rendered. In my App I also have a tree-view like view with > 1000 items. I ended up using a ListBox with a MarginConverter and using DynamicData to filter out collaped items. Cannot share it here for reasons, but the idea should be clear enogh to implement it on your side if you hit performance issues.
@timunie Yes this is definitely something we will try to cache the images as the current SvgImage integration loads all indiviudal images even those are mainly the same, like e.g.: Lock or Eye icons. So in reality we would only need to cache about 20-30 images and then use those in the nodes/subnodes/.... As you see below, those are many but most of them similar so no need to load them a hundred times.
As I mentioned before we needed to switch from ListBox to TreeView as ListBox was reacting really abd with the images and in case many layers where expanded it always lead to memory overflow on scrolling. I am confident that we will get this working with treeview. Will keep you updated ;).
Just to chime in as I am facing a similar issue. I'm using the TreeDataGrid with thousands of nodes and was using SVG images as well. What I noticed was some lag in Debug mode on my devbox which went away when no debugger was attached in release mode but on older/slower hardware the lag was still quite noticeable. Removing the image also removed the lag and everything was buttery smooth. So the lag is definitely related to using images.
I did some quick testing by caching the images beforehand and the lag was immediately gone - even in debug mode.
okay one last comment here. The icons look really "plain" svg pathes. In such cases I only use PathIcon
control and set Data to a StreamGeometry placed in resources. Additional benefit: I can be styled :-)
@timunie and Stefan. Ok this sound promising so we will definitely go for caching and also test the PathIcon approach. Thanks for your input. I will inform you once we changed ang tested it.
BTW - we are currently using the Avalonia.Svg.Skia.SvgImageExtension so this seems to have no caching options
I guess we will need to write a wrapper arround this ? So an extension of SvgImageExtension probably
That's correct. What I did was simply putting the Source (IImage) into a dictionary and use this in case it's already there. You may need to inherit from Image or have a custom converter to do this.
@StefanKoell and @timunie Thanks for assistance the final implementation works perfect now. We are using the Avalonia TreeView combined with ImageCaching, now switching between documents and upating the tree even with IsExpanded states work within milliseconds. Solved from my point of view.
TreeView
Caching
Describe the bug With many objects loaded into the tree, scrolling and general application responsiveness are negatively affected
To Reproduce Steps to reproduce the behavior:
Load many objects with hierarchy into a TreeView. Expand all expandable nodes. Testing here with 5000 entries.
Expected behavior TreeView should be able to handle many entries (possibly via virtualization?)
Desktop (please complete the following information):
Tested on Windows 10 and RHEL 8
Additional context Tree objects look like this:
TreeView bindings look like this: