Ways to improve WPF UI rendering speed

rem picture rem · Mar 23, 2011 · Viewed 47.1k times · Source

In case a screen of a WPF application contains lots of primitive controls, its rendering becomes sluggish. What are the recommended ways to improve the responsiveness of a WPF application in such a case, apart from adding fewer controls and using more powerful videocard?

Is there a way to somehow use offscreen buffering or something like that?

Answer

Alex Zhevzhik picture Alex Zhevzhik · Mar 23, 2011

Our team was faced with problems of rendering performance. In our case we have about 400 transport units and we should render chart of every unit with a lot of details (text labels, special marks, different geometries etc.).

In first our implementations we splitted each chart into primitives and composed whole unit's chart via Binding. It was very sad expirience. UI reaction was extremely slow.

So we decided to create one UI element per each unit, and render chart with DrawingContext. Although this was much better in performance aspect, we spent about one month improving rendering.

Some advices:

  1. Cache everything. Brushes, Colors, Geometries, Formatted Texts, Glyphs. (For example we have two classes: RenderTools and TextCache. Rendering process of each unit addresses to shared instance of both classes. So if two charts have the same text, its preparation is executed just once.)
  2. Freeze Freezable, if you are planning to use it for a long time. Especially geometries. Complex unfreezed geometries execute HitTest extremely slow.
  3. Choose the fastest ways of rendering of each primitive. For example, there is about 6 ways of text rendering, but the fastest is DrawingContext.DrawGlyphs.
  4. Use profiler to discover hot spots. For example, in our project we had geometries cache and rendered appropriate of them on demand. It seemed to be, that no improvements are possible. But one day we thought what if we will render geometries one time and cache ready visuals? In our case such approach happened acceptable. Our unit's chart has just several states. When data of chart is changed, we rebuild DrawingVisual for each state and put them into cache.

Of course, this way needs some investments, it's dull and boring work, but result is awesome.

By the way: when we turned on WPF caching option (you could find link in answers), our app hung up.