Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ways to improve WPF UI rendering speed

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?

like image 971
rem Avatar asked Mar 23 '11 06:03

rem


People also ask

Is WPF fast?

In general, WPF is perfoming much worse in drawing performance than Windows Forms, and native GDI or DirectX. Yes, WPF is powerful in the sense you might make some neat stuff that is not supported in GDI, but it is more sluggish.

Does WPF use GPU?

The GPU, or Graphics Processing Unit, is the chip that powers your video card. Essentially, hardware acceleration offloads the work of rendering graphics in your WPF application from your computer's main processor (CPU) to the video card's processor (GPU).

How does WPF rendering work?

WPF uses vector graphics as its rendering data format. Vector graphics—which include Scalable Vector Graphics (SVG), Windows metafiles (. wmf), and TrueType fonts—store rendering data and transmit it as a list of instructions that describe how to recreate an image using graphics primitives.


1 Answers

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.

like image 146
Alex Zhevzhik Avatar answered Oct 10 '22 13:10

Alex Zhevzhik