I currently work in a customer assignment related to performance problems in a WPF rich client LOB application.
The problem is that the application runs very slow/sluggish. Especially data table handling (scrolling, sorting, selection) is extremely slow and leaves the application unusable.
I analyzed the system state when a single tab containing a few textboxes, comboboxes and labels is opened and left idle (waiting for user input).
These are my findings:
- All the rendering is calculated on the GPU
- There are no performance heavy features such as animations, bitmap effects, transparency, etc.
- When the tab is idle (only the cursor is blinking in the focused textbox, the rest of the tab is static and does not even contain any data) the GPU runs up to 90%
- GPU drops to 0 whenever the tab loses focus
- GPU percentage directly relates to the window size. A small window brings it down to a few percent, full screen makes it go up to almost 100%
- WPF Perforator tells me that WPF calculates the dirty region for the entire tab instead of only the blinking cursor
- WPF Perforator reports dirty rect update rates larger than 20/sec on the idle tab and they directly correlate to GPU usage
My conclusion: During development a lot of custom code (layout, event handling, etc..) has been introduced in order to fit WPF to the backend-driven architecture of the system as a whole. My guess is that due to some of the custom code the dirty-rect-mechanism of WPF has been broken. This leads to too much drawing activity and thus very high GPU usage. These innecessary activities lead to the problems described above.
Now I am looking for any advice where I should start my investigation. Or in other words: What are typical mistakes that a developer can make in order to break the WPF dirty-rect update algorithm. Any input is highly appreciated.
Many thanks and best regards!
Manuel