10 WPF Performance Tricks for 2020
Kuntal(KJ) Mehta
CTO Seashore Solutions | Zoho Creator Partner | Logitrac360 | Zoho expert | WMS & MFG ERP
In the run for making it more and more prominent, Windows Presentation Foundation (WPF) developers have figured out what best can be done, and can be made a regular practice when it comes to WPF development services.
Are you a Windows Presentation Foundation (WPF) developer? Or let me twist my question a bit, "Are you too a WPF developer whose applications are suffering from a poor performance?"
There are plenty of tips and tricks online, but here are some tactics that might help you to enhance and improvise your WPF application development techniques.
#1 Enable Container Recycling
ItemsControls are the most certain to trouble your application, reason - they are not virtualized. This means that they are continuously being created and are destroyed for each and every item in the control. You can rather use the VirtualizingStackPanel as the items host, make use of VirtualizingStackPanel.IsVirtualizing and set VirtualizationMode to 'recycling' so that the item containers can be reused instead of creating new ones all the time.
#2 Dispatch Expensive Calls
At the time of WPF application development, dispatch expensive calls either within UI thread using the lower DispatcherPriority by calling Dispatcher.BeginInvoke() or to a background thread using a BackgroundWorker to maintain the responsiveness of the UI.
#3 Choose StaticResources Over DynamicResources
The StaticResources always provide values for any XAML property by referring to an already defined resource. This lookup behavior is exactly the same as the compile-time lookup. When it comes to DynamicResources, it will create a temporary expression and will defer the lookup for resources until there is a requirement for the resource value. Now, this lookup behavior is the same as a run-time lookup, which then causes a huge impact when it comes to performance. Hence, use StaticResources wherever possible.
#4 Reduce Visuals
Whenever you are into providing WPF development services, make sure that you always try to reduce the number of visuals by removing the elements that are least or not required. Combine the layout panels and simplify the templates. This keeps the memory footprint small, optimized, and improves rendering performance.
#5 Freeze The Freezables
Freeze Freezables whenever into WPF application development by calling Freeze() in code or PresentationOptions:Freeze="true" in XAML. This eases off the memory consumption and eventually improves the performance. This is because the system, then, doesn't need to monitor any changes.
#6 Use StreamGeometries
Use the StreamGeometries instead of PathGeometries whenever possible to draw complex 2D geometries. They are way more efficient, consume lesser memory, and enhances performance.
#7 Lower the BitMapScalingMode
WPF application development by default uses a high-quality image re-sampling algorithm which consumes a lot of system resources which later on result in frame rate degradation and affect the animations badly, cause them to stutter. To improvise your performance, set the BitMapScalingMode to LowQuality and witness a 'speed-optimized' algorithm instead of 'quality-optimized' algorithm.
#8 Separate Thread for Separate Data
While WPF application development, developers come across a very common source of performance problems, frozen UI, apps stop responding whenever load data. Make sure that your data is asynchronously being loaded on a separate thread as to not overload the UI thread. Loading the data on a UI thread will end up in the poorest of performances and overall end-user experience. Multi-threading is something that every WPF development service provider should use in their application and development processes.
#9 NeutralResourcesLanguage Attribute - In-Play
Use the NeutralResourcesLanguage attribute to tell the ResourceManager about the neutral culture and avoid unnecessary and unsuccessful satellite assembly lookups.
#10 Take Care of Memory Leaks
Memory leaks are the most prior cause of performance problems when it comes to WPF application development. They are really easy to have but equally difficult to find. Let’s say, using DependencyPropertyDescriptor.AddValueChanged can cause the WPF framework to take a strong reference to the source of the event that is not removed until and unless you manually call DependencyPropertyDescriptor.RemoveValueChanged. If the behaviors rely on events erupted from an object or ViewModel (such as INotifyPropertyChanged), subscribe to them either weakly or unsubscribe manually. Also, if at all you are binding to properties in a ViewModel which does not implement INotifyPropertyChanged, there are very high chances that you would suffer memory leak.
Conclusion
Sometimes there can be one or multiple issues with your application that is really hard or nearly impossible to identify. With this statement, comes a bonus pro tip. Using an application profiler will help you identify where exactly are the issues occurring in your codebase. There are plenty of profiler options available - paid and free, both. The best one is the Diagnosis Tools built directly into Visual Studio 2019.
About Author:
Shrikant has been working in the IT industry for more than 7 years across different sectors, designing and developing various enterprise-level software systems ranging from desktop apps, kiosk, websites, IoT, and systems. Also expert in developing a system that helps in manufacturing industry/process automation by integrating custom control boards (PLR/PLC).
Are you looking to hire WPF developers for your next project? Get in touch with our team.
Product Manager at DevExpress | .NET MAUI | WPF | WinForms
1 年Noticed this useful article and decided to supplement it with several additional startup performance tips: 1.Generate native images using Ngen.exe 2.Use MultiCore JIT if Ngen is not applicable 3.Use ReadyToRun in conjunction with MultiCore JIT for .NET Core (.NET 6/7) projects, since there is no Ngen for them 4.Load Data on Demand. I think is is not your case, but may be useful for the full picture. For example, DevExpress components have?Virtual Source?and?Server Mode?features to do this asynchronously for you. 5. You can also wrap "heavy" views in in controls that delay their loading without freezing the UI. For example, you can use?DevExpress LoadingDecorator 6.Make sure that your view controls are not expanded of outside the visible area. For example, if you have StackPanel with ListBox inside, ListBox will create all its elements at once, because StackPanel doesn't limit height for its children, and they "think" that they have infinite height. As a result, ListBox will create all visual elements at once and significantly decrease your performance. Here is a blog post that might be helpful: https://community.devexpress.com/blogs/wpf/archive/2023/01/26/9-tips-to-reduce-wpf-app-startup-time.aspx