Performance considerations
While developing software, it is very important to keep an eye on the performance. Catel itself does perform very well, but there are some caveats that you should be aware of. If you have the feeling that the application is laggy or slow, or if you want to make sure to squeeze the best performance out of Catel, consider taking a closer look at the checklist below.
Use the ApiCop feature to get a detailed advisory report on your software
General
Disable the call to LogManager.AddDebugListener
The DebugListener
is a very useful class while developing an application. It throws all the logging of Catel to the output window of Visual Studio which allows you to view exactly what happens behind the scenes. However, writing all these logs to the output window is very expensive and might cause an application to perform badly.
Therefore, it is important to disable any call to LogManager.AddDebugListener
when releasing an application or while performance testing.
Best way to deal with this is to wrap it inside the DEBUG
define:
#if DEBUG
LogManager.AddDebugListener();
#endif
Preloading assemblies into the AppDomain
Preloading assemblies might result in a slower startup time, but will not cause slow downs for reflection or assembly loading during the actual application execution. To preload assemblies using Catel, simply call this extension method:
** **
WPF application
In App.xaml.cs, add the following code
var directory = typeof(MainWindow).Assembly.GetDirectory();
AppDomain.CurrentDomain.PreloadAssemblies(directory);
ASP.NET application
In global.asax, add the following code:
var directory = Server.MapPath("~/bin");
AppDomain.Current.PreloadAssemblies(directory);
Warming up the serializers
To improve performance for serialization, warm up the serializers.
MVVM
Set SkipSearchingForInfoBarMessageControl on UserControl to true
By default, Catel assumes that an InfoBarMessageControl is located on any window. However, it might be that this control is not located on a window that contains an instance of the UserControl class. This might decrease the performance, especially when lots of user controls are used in a hierarchical way. The cause is that the UserControlLogic searches for an InfoBarMessageControl to register the view model to.
If no InfoBarMessageControl is located on a container, make sure to set SkipSearchingForInfoBarMessageControl to true.
// Use when not using styles and transitions
Catel.Windows.Controls.UserControl.DefaultTransferStylesAndTransitionsToViewModelGridValue = false;
// Use when not using any validation controls
Catel.Windows.Controls.UserControl.DefaultSkipSearchingForInfoBarMessageControlValue = true;
Catel.Windows.Controls.UserControl.DefaultCreateWarningAndErrorValidatorForViewModelValue = false;
Use the FastObservableCollection
The FastObservableCollection does not raise events for every item, but only invokes events for the complete range of items added to or removed from the collection.
When modifying a large collection of items, it is not required to raise change events for each added / removed value. Therefore the FastObservableCollection will disable change notifications until the full collection modification is done and then raise the change events just once.
Use the FastObservableDictionary
Designed in a similar fashion to the FastObservableCollection
, the FastObservableDictionary
is meant for Views that need to leverage the power of a dictionary for controls such as ComboBox
without sacrificing performance and providing real-time feedback to the user.
In addition to implementing FastObservableDictionary
, any implementations of a ComboBox
should leverage a VirtualizingStackPanel
to minimize the amount of elements rendered at a given time. An example is provided below:
<ItemsPanelTemplate x:Key="VirtualizingItemsPanelTemplate">
<VirtualizingStackPanel />
</ItemsPanelTemplate>
<CombBox DisplayMemberPath="Value"
ItemsSource="{Binding Options}"
ItemsPanel="{StaticResource VirtualizingItemsPanelTemplate}"
SelectedValuePath="Key"
SelectedItem="{Binding SelectedItem}" />
Specify throttling on the ViewModelBase
The ViewModelBase allows the specify the throttling of the property change notifications. In normal situations it is best to directly raise property change notifications. However, when a lot of properties change a lot within a very short timeframe, it might be interesting to enable throttling. By using throttling, the change notifications are not directly sent to the UI but instead added to a dictionary. Then each time the ThottlingRate is reached, the change notifications are sent in batches to the view. If the same property has changed several times in a specific time frame, it will only be raised once which might give a performance boost in very specific situations.
By default, throttling is disabled but can be enabled by setting the ThrottlingRate property:
ThrottlingRate = new TimeSpan(0, 0, 0, 0, 200);
The AdvancedDemo example contains a demo that shows the impact of throttling
Contributions
We would like to thank the following contributors:
Want to contribute to the documentation? We have a guide for that!
Questions
Have a question about Catel? Use StackOverflow with the Catel tag!