提高 WPF UI 渲染速度的方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5401549/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Ways to improve WPF UI rendering speed
提问by rem
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?
如果 WPF 应用程序的屏幕包含大量原始控件,则其渲染会变得缓慢。在这种情况下,除了添加更少的控件和使用更强大的视频卡之外,还有哪些推荐的方法可以提高 WPF 应用程序的响应能力?
Is there a way to somehow use offscreen buffering or something like that?
有没有办法以某种方式使用屏幕外缓冲或类似的东西?
回答by Alex Zhevzhik
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.).
我们的团队面临着渲染性能的问题。在我们的例子中,我们有大约 400 个运输单元,我们应该用很多细节(文本标签、特殊标记、不同的几何图形等)渲染每个单元的图表。
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.
在我们的最初实现中,我们将每个图表拆分为基元并通过绑定组合整个单元的图表。这是非常悲伤的经历。UI 反应极其缓慢。
So we decided to create oneUI element per each unit, and render chart with DrawingContext. Although this was much better in performance aspect, we spent about one month improving rendering.
所以我们决定为每个单元创建一个UI 元素,并使用 DrawingContext 渲染图表。虽然这在性能方面要好得多,但我们花了大约一个月的时间来改进渲染。
Some advices:
一些建议:
- Cache everything. Brushes, Colors, Geometries, Formatted Texts, Glyphs. (For example we have two classes:
RenderTools
andTextCache
. 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.) - Freeze
Freezable
, if you are planning to use it for a long time. Especially geometries. Complex unfreezed geometries execute HitTest extremely slow. - 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
. - 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.
- 缓存一切。画笔、颜色、几何图形、格式化文本、字形。(例如我们有两个类:
RenderTools
和TextCache
。每个单元地址的渲染过程到两个类的共享实例。因此如果两个图表具有相同的文本,则其准备只执行一次。) - 冻结
Freezable
,如果您打算长期使用它。尤其是几何图形。复杂的未冻结几何图形执行 HitTest 非常慢。 - 选择渲染每个图元的最快方式。例如,文本渲染大约有 6 种方式,但最快的是
DrawingContext.DrawGlyphs
. - 使用分析器发现热点。例如,在我们的项目中,我们缓存了几何图形并按需渲染它们。似乎没有任何改进是可能的。但有一天我们想,如果我们一次性渲染几何图形并缓存准备好的视觉效果会怎样?在我们的案例中,这种方法是可以接受的。我们单位的图表只有几个状态。当图表的数据发生变化时,我们为每个状态重建 DrawingVisual 并将它们放入缓存中。
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.
顺便说一句:当我们打开 WPF 缓存选项(你可以在答案中找到链接)时,我们的应用程序挂了。
回答by David
I've had the same perf issue with a heavily customized datagrid since one year, and My conclusion is:
自一年以来,我在高度定制的数据网格上遇到了同样的性能问题,我的结论是:
there is basically nothing you can do on your side (without affecting you app, i.e.: having fewer controls or using only default styles)
您基本上无能为力(不影响您的应用程序,即:控件较少或仅使用默认样式)
The link mentioned by Jens is great but useless in your case.
Jens 提到的链接很好,但对您来说没用。
The "Optimizing WPF Application Performance" link provided by NVM is almost equally useless in my experience: it just appeals to common sense and I am confident you won't learn anything extraordinary either reading. Except one thing maybe: I must say this link taught me to put as much as I can in my app's resource. Because WPF does not reinstanciate anything you put in resource, it simply reuses the same resource over and over. So put as much as you can in there (styles, brushes, templates, fonts...)
NVM 提供的“优化 WPF 应用程序性能”链接在我的经验中几乎同样无用:它只是诉诸常识,我相信无论阅读还是阅读,您都不会学到任何非凡的东西。除了一件事:我必须说这个链接教会我在我的应用程序资源中尽可能多地投入。因为 WPF 不会重新实例化您放入资源中的任何内容,它只是一遍又一遍地重用相同的资源。所以尽可能多地放进去(样式、画笔、模板、字体……)
all in all, there is simply no way to make things go faster in WPF just by checking an option or turning off an other. You can just pray MS rework their rendering layer in the near future to optimize it and in the meantime, try to reduce your need for effects, customized controls and so on...
总而言之,仅仅通过检查一个选项或关闭另一个选项,根本无法使 WPF 中的事情变得更快。您可以祈祷 MS 在不久的将来重新设计他们的渲染层以对其进行优化,同时,尽量减少对效果、自定义控件等的需求……