Search code examples
.netwpfperformancexamlbaml

Performance problem loading lots of user controls


My application is loading a bunch of the same user control into a ScrollPanel. The problem is, this is very slow.

The profiler shows that the bottleneck is the method Application.LoadComponent(), which is called internally from the constructor of my user control. The documentation of this method says that this method loads XAML files.

The question is, how can I use BAML instead of XAML? How can I accomplish that the XAML for my user control must not be parse again and again when creating new instances from it? Is there another way to make loading my user controls faster?


Solution

  • LoadComponent() already loads .baml, don't worry about this bit of the question. Microsoft did this intentionally, to not let developers make dependencies on baml format. Going forward they can improve the format without breaking any existing applications.

    Yes, there are another ways of making it work faster. The first optimization to take is UI virtualization. WPF already comes with handy VirtualizingStackPanel. It works in tandem with ItemsControls, and has certain limitations (e.g. if you create items containers and add them by your own, you loose virtualization, or if you set ScrollViewer.CanContentScroll="False" you loose it again). To use virtualization you will probably have to rewrite your application to use ItemsControl + DataBinding style (ListBox already has virtualization enabled)

    If you feel like you need even more information on UI virtualization refer to Dan Crevier's blog.

    And final advice. You can try rewriting your UserControls to Custom Controls. My simple performance test showed the following figures. To create 10K controls with the same visual tree it took:

    • for UserControl: 4932ms;
    • for CustomControl: 86ms; (~57 times faster)

    Hope this helps