Trying to see what can I change to improve performance for RadDiagram.
1- The goal is to show 2000+ hexagon.
2- Every hexagon has the same size, but it's color content might change. Every hexagon has a binding to a Viewmodel item.
3- Hexagons are grouped inside containers. The containers are pretty much transparent, except for its header.
4- There are no connectors and for now at least, users can't drag/delete/add items.
5- The diagram is contained inside a RadDocking and the docking is inside a regular WPF Tab.
When testing with 300 items there is a 4 second wait after the UI is loaded until the UI can be interacted with.
I am wondering, giving my scenario, what can I do to improve performance, giving that after loading the nodes don't change position/size.
9 Answers, 1 is accepted
You can take a look at the Tips and Tricks help article which describes a few things which you could try to increase the performance. The diagram control supports a UI virtualization which means that it will hide all items that are outside of the viewport. However, even then on load, the diagram will generate the layout slots (the containers) for all items, including those outside the viewport. In a scenario with 2000+ elements, this could be a quite slow operation. However, this comes from the rendering engine of the WPF framework and the diagram can't make much for improving the performance. We can think of a way to improve the virtualization process to avoid generating all containers, but at this point, we can't boost the load time of such a big amount of items.
I did take a look at that and I am already following all the recommendations that apply to us.
"We can think of a way to improve the virtualization process to avoid generating all containers".Is there something we could investigate for now?
We prepared a sample projects for you to test a scenario similar to yours. 500 shapes into container need about 1.2 to 1.6 seconds to load. Can you please check out the test projects and let us know for a possible differences between them and your scenario. 4 seconds seems a lot to us for for 300 shapes. as my colleague Dinko said, we are aware of performance issues with hundreds of items, however, with details from your side we could eventually identify and log areas for improvement in our Diagram Framework.
The MVVM projects uses ObservableGraphSource to bind the Diagram. We add 1 container shape and 500 shapes. If we add container and shapes separately into diagram the load time is about 1.3 seconds. The downside of this is that shapes are not draggable via container and they are not logical children of the container. However, in your scenario you might not need this - you may use the container only for visual grouping and no dragging. If you add the shapes into the container first, then add the container to the graphsource, the load time is about 1.6 seconds mainly because on load , on every child add container tries tor resize itself to fit the children.
We have also prepared a non-MVVM project in which shapes are directly added to diagram and no graphsource is used. Load time is about 1.2-1.3 seconds and there is no big difference if you add the shapes into diagram vs into container first. We will investigate this difference with MVVM separately.
I hope the projects will give you an idea for the difference in your scenario compared to the test one. Also, we will update you tomorrow with Diagram with Custom Shape. We will try to isolate visual parts of shapes not needed - Connectors Canvas, Editing TextBox. For this purpose - can you please elaborate all UI actions you need for your shapes - dragging, selection, editing, rotating, resizing, do you need text wrapping, do you need borders, strokes, stroke dash arrays.
Thank you in advance for your cooperation.
Sorry for taking so long to reply!
We are not using any action on the shapes for now. We will draw them once, and they will change colors depending on internal events.
We are using transparent containers that contain a list of hexagons. The containers are displayed using autolayout, and the hexagons inside the containers are manually positioned.
We are not using connects, editing, draggin, text wrapping or anything of sorts.
Thanks, looking forward to your update.
Since you don't need many of the shape's features, you can consider implementing custom shape which has simplified template. I added such shape in a sample project where 1000 hexagon shapes are loaded in Diagram for less than 1 second. I hope it will give you a basic idea of how to proceed on your side. We will soon have such example on SDK but it will be pretty much the same as the one attached here. Please note that the example uses no-xaml binaries which is generally faster than using xaml binaries.
Let me know if you have any further questions.
Thanks a lot for the example. It works great using code-behind,but in order to have it working with xaml, I had to do a couple modifications to the project, which increase the time a bit. Is there something I could do for that?
Modifications i had to do
Adding nodes to VM:
PS: I am also using no-xaml binaries.
I've tested your code with Peter's solution, and indeed the performance is a bit slower. On my side less than a second (~600-800ms). This is expected since you include an additional level of abstraction which executes some more logic in the diagram and the WPF framework.
I've looked for a way to improve the performance in this case, and I was able to get the loading time down to ~3.3 sec, instead of the ~3.7 sec, which was my original loading time. This was done by overriding the AddNode() of the graph source class.
If you don't need to show content (like text) inside the hexagons, you can remove also the ContentPresenter and the parent Grids from the ControlTemplate of the CustomShape. This will leave only a single Path (for the geometry) in it. The loading time decreases with ~1 sec on my side after doing this.
That is fantastic.
I've also added events pre/post updating nodes to disable notification (which also helped improve the performance as well).
We will do another round of performance testing this week! Thanks!