WPF程序性能

WPF程序性能由很多因素造成,以下是简单地总结:

元素:

1、  减少需要显示的元素数量:去除不需要或者冗余的XAML元素代码. 通过移出不必要的元素,合并layout panels,简化templates来减少可视化树的层次。这可以保证第内存使用,而改变渲染性能。

2、  UI虚拟化:只显示当前需要显示的元素.

3、  不要把不要显示的自定义控件隐藏在主界面中:虽然它们不会显示出来,但是程序启动时还是会去计算自定义控件所需的空间和位置.

4、  VirtualizingStackPanel对Item类型控件重写时,使用VirtualizingStackPanel作为ItemPanel,这样列表资源可以只渲染当前需要的内容。不过如果设置CanContextScrol="True"会阻止虚拟化,另外使用VirtualizingStackPanel时,可以设置VirtualizingStackPanel.VirtualizationMode="Recycling", 这样已经显示过的列表不会被重复创建和释放掉。

5、  冻结可以冻结的控件:通过在代码中调用Freeze()或者在Xmal中设定PresentationOptions:Freeze="true"来冻结可以冻结的控件。由于这样系统不必监听该控件的变化,所以可以带来性能的提升.

6、  尽可能使用StreamGeometries 代替PathGeometries:因为它可以一低内存占用,更高效.

7、  尽量多使用Canvas等简单的布局元素:少使用Grid或者StackPanel等复杂的,越复杂性能开销越大

8、  尽量不要使用ScrollBarVisibility=Auto

9、  如果需要修改元素的Opacity属性,最后修改一个Brush的属性,然后用这个Brush来填充元素。因为直接修改元素的Opacity会迫使系统创建一个临时的Surface

10、 使用延迟滚动增强用户体验:如果你还记得可滚动的DataGrid或ListBox,它们往往会降低整个应用程序的性能,因为在滚动时会强制连续更新,这是默认的行为,在这种情况下,我们可以使用控件的延迟滚动(Deferred Scrolling)属性增强用户体验。你需要做的仅仅是将IsDeferredScrollingEnabled附加属性设为True

11、 使用容器回收提高性能: 你可以通过回收执行虚拟化的容器来提高性能,下面的代码片段将ViruatlizationMode设为Recycling,它让你可以获得更好的性能。当用户滚动或抵达另一个项目时,它强制重复使用容器对象。

线程:

1、  耗时操作放在放在非UI线程上处理,保持UI的顺畅:处理完成后如果需要在UI上展示,调用Dispatcher.BeginInoke()方法

绑定:

1、  Mode关于Data Binding,根据实际情况对Binding指定不同的Mode,性能比较:OneTime>OneWay>TwoWay。

2、  修正系统中Binding错误:在Visual Studio的输出日志中查找System.Windows.Data Error。

3、  在使用数据绑定的过程中,如果绑定的数据源是一个CLR对象,属性也是一个CLR属性,那么在绑定的时候对象CLR对象所实现的机制不同,绑定的效率也不同。

4、  访问CLR对象和CLR属性的效率会比访问DependencyObject/DependencyProperty高。注意这里指的是访问,不要和前面的绑定混淆了。但是,把属性注册为DependencyProperty会有很多的优点:比如继承、数据绑定和Style。

5、  数据源是一个CLR对象,属性也是一个CLR属性。对象通过TypeDescriptor/PropertyChanged模式实现通知功能。此时绑定引擎用TypeDescriptor来反射源对象。效率最低。

6、  数据源是一个CLR对象,属性也是一个CLR属性。对象通过INotifyPropertyChanged实现通知功能。此时绑定引擎直接反射源对象。效率稍微提高。

7、  数据源是一个DependencyObject,而且属性是一个DependencyProperty。此时不需要反射,直接绑定。效率最高。

8、  当一个CLR对象很大时,比如有1000个属性时,尽量把这个对象分解成很多很小的CLR对象。比如分成1000个只有一个属性的CLR对象。

9、  当我们在列表(比如ListBox)显示了一个CLR对象列表(比如List)时,如果想在修改List对象后,ListBox也动态的反映这种变化。此时,我们应该使用动态的ObservableCollection对象绑定。而不是直接的更新ItemSource。两者的区别在于直接更新ItemSource会使WPF抛弃ListBox已有的所有数据,然后全部重新从List加载。而使用ObservableCollection可以避免这种先全部删除再重载的过程,效率更高。

10、       尽量绑定IList而不是IEnumerable到ItemsControl。

资源:

1、  通常情况下我们会把样式资源都统一到App.xaml中,这是很好的,便于资源的管理。

2、  尽量把多次重复用到的资源放到App.xaml中。例如某些页面的资源只会在当前页面中使用到,那么可以把资源定义在当前页面; 因为放在控件中会使每个实例都保留一份资源的拷贝。

3、  如非必要,不要使用DynaicResource,使用StaticResource即可;

动画:

1、  尽量少的使用Animation:程序启动时,Animation渲染时会占用一些CPU资源。

2、  降低动画的帧率:大多数动画不需要高帧率,而系统默认为60frames/sec,所以可以设定Storyboard.DesiredFrameRate 为更低值。

3、  使用卸载事件卸载不必要的动画:动画肯定会占用一定的资源,如果处置方式不当,将会消耗更多的资源,如果你认为它们无用时,你应该考虑如何处理他们,如果不这样做,就要等到可爱的垃圾回收器先生来回收资源。

4、

图像:

1、   对Image做动画处理的时候(如调整大小等),可以使用这条语句RenderOptions.SetBitmapScalingMode(MyImage,BitmapScalingMode.LowQuality),以改善性能。

2、   用TileBrush的时候,可以CachingHint。

3、  预测图像绘制能力:根据硬件配置的不同,WPF采用不同的Rendering Tier做渲染。下列情况请特别注意,因为在这些情况下,即使是处于Rendering Tier 2的情况下也不会硬件加速。(不全,其余请查阅SDK)

文本:

1、  文字少的时候用TextBlock或者label,长的时候用FlowDocument.

2、  使用元素TextFlow和TextBlock时,如果不需要TextFlow的某些特性,就应该考虑使用TextBlock,因为它的效率更高。

3、  在TextFlow中使用UIElement(比如TextBlock)所需的代价要比使用TextElement(比如Run)的代价高.在FlowDocument中尽量避免使用TextBlock,要用Run替代。

4、  在TextBlock中显式的使用Run命令比不使用Run命名的代价要高。

5、  把Label(标签)元素的ContentProperty和一个字符串(String)绑定的效率要比把字符串和TextBlock的Text属性绑定的效率低。因为Label在更新字符串是会丢弃原来的字符串,全部重新显示内容。如果字符串不需要更新,用Label就无所谓性能问题。

6、  在TextBlock块使用HyperLinks时,把多个HyperLinks组合在一起效率会更高。

7、  显示超链接的时候,尽量只在IsMouseOver为True的时候显示下划线,一直显示下划线的代码高很多

8、  尽量不使用不必要的字符串连接

9、  使用字体缓存服务提高启动时间:WPF应用程序之间可以共享字体数据,它是通过一个叫做PresentationFontCache Service的Windows服务实现的,它会随Windows自动启动。你可以在控制面板的“服务”中找到这个服务(或在“运行”框中输入Services.msc),确保这个服务已经启动。

其他:

1、  用NavigationWindow的时候,尽量Update the client area by object,而不是URI

2、  建立逻辑树或者视觉树的时候,遵循Top-Down的原则

3、  使用WPF分析工具分析WPF程序:分析WPF程序是理解其行为很重要的一步,市场上有大量现成的WPF程序分析工具,如Snoop,WPFPerf,Perforator和Visual Profiler,其中Perforator和Visual Profiler是WPF Performance Suite的一部分,要了解这些工具的用法,请去它们的项目主页。

时间: 2024-10-17 01:26:07

WPF程序性能的相关文章

提高WPF程序性能的几条建议

这篇博客将介绍一些提高WPF程序的建议(水平有限,如果建议有误,请指正.) 1. 加快WPF程序的启动速度: (1).减少需要显示的元素数量,去除不需要或者冗余的XAML元素代码. (2).使用UI虚拟化,只显示当前需要显示的元素. (3).不要把不要显示的自定义控件隐藏在主界面中,虽然它们不会显示出来,但是程序启动时还是会去计算自定义控件所需的空间和位置. 2. 耗时操作放在放在非UI线程上处理,保持UI的顺畅.处理完成后如果需要在UI上展示,调用Dispatcher.BeginInoke()

细数改善WPF应用程序性能的10大方法

WPF(Windows Presentation Foundation)应用程序在没有图形加速设备的机器上运行速度很慢是个公开的秘密,给用户的感觉是它太吃资源了,WPF程序的性能和硬件确实有很大的关系,越高档的机器性能越有优势. 程序性能改善不是一蹴而就的,好的设计可以消除影响性能的问题,例如,在运行时构造对象就会对程序的性能造成影响.虽然WPF通过增强的导航等功能提供了更丰富的用户界面,但你应该考虑你的用户是否的确需要富图形界面,尽管WPF有这样那样的问题,但在UI设计,特别是自定义风格和控件

改善WPF应用程序性能的10大方法 (转发)

WPF(Windows Presentation Foundation)应用程序在没有图形加速设备的机器上运行速度很慢是个公开的秘密,给用户的感觉是它太吃资源了,WPF程序的性能和硬件确实有很大的关系,越高档的机器性能越有优势. 程序性能改善不是一蹴而就的,好的设计可以消除影响性能的问题,例如,在运行时构造对象就会对程序的性能造成影响.虽然WPF通过增强的导航等功能提供了更丰富的用户界面,但你应该考虑你的用户是否的确需要富图形界面,尽管WPF有这样那样的问题,但在UI设计,特别是自定义风格和控件

最优化WPF 3D性能(基于“Tier-2”硬件)

原文:最优化WPF 3D性能(基于"Tier-2"硬件) 原文地址:Maximizing WPF 3D Performance on Tier-2 Hardware 开发人员在应用程序中使用Windows Presentation Foundation来构建大量的3D控件.包含3D场景时,常常会遇到如何优化其性能的问题.WPF 3D组的几个成员提供了一个影响应用程序性能的3D类和属性的列表.当我们使用她们来优化应用程序性能时应该遵从这些建议. 本随笔假定你深刻的理解了WPF 3D AP

以C语言为例的程序性能优化 --《深入理解计算机系统》第五章读书笔记

其实大多数的编译器本身就能提供一些简单的优化,比如gcc就能通过使用 -O2 或者 -O3 的选项来优化程序.但编译器的优化始终也是有限,因为它必须小心翼翼保证优化过程不对程序的功能有改动.故而程序员本身应该对程序有优化意识.在我看来,这也是应该有的一种良好的编程习惯. 几种比较简单的优化措施: 1.代码移动 将要执行多次(比如在循环中)但计算结果不会改变的计算,移动到代码前面不会多次求值的部分.举一个比较极端的例子: /* convert string to lowercase: slow*/

Java程序性能优化——性能调优层次

为了提升系统性能,开发人员可以从系统的各个角度和层次对系统进行优化.除了最常见的代码优化外,在软件架构上.JVM虚拟机层.数据库以及操作系统层都可以通过各种手段进行调优,从而在整体上提升系统的性能. 设计调优 设计调优处于所有调优手段的上层,它往往需要在软件开发之前进行.在软件开发之初,软件架构师就应该评估系统可能存在的各种潜在的问题,并给出合理的设计方案.由于软件设计和架构对软件整体有决定性的影响,所以,设计调优对系统性能的影响也是最大的.如果说,代码优化.JVM优化都是对系统微观层面上"量&

WPF实践系列1 of n 自定义WPF程序的Main函数

关于开篇 由于业务需要参与到一个Window下的WPF项目中.因为之前的工作环境一直在Linux下,C和C++作为主力开发语言, 因此加入新项目对自己来说是变化,同时也是挑战:学点新东西拓宽下视野. 关于WPF实践系列 项目是个中型的Windows客户端,需要通过网络和SQL服务器交互.由于有多版本兼容需求(xp-win10)和高分屏需求,选了WPF方案,在Visual Studio 2017下进行开发. 博主目前对WPF和 .Net这些知识仅是略知一二.取名实践系列,意指在过程中边做边学.主要

提高ASP.NET应用程序性能的十大方法

一.返回多个数据集 检查你的访问数据库的代码,看是否存在着要返回多次的请求.每次往返降低了你的应用程序的每秒能够响应请求的次数.通过在单个数据库请求中返回多个结果集,可以减少与数据库通信的时间,使你的系统具有扩展性,也可以减少数据库服务器响应请求的工作量. 如果你是用动态的SQL语句来返回多个数据集,那我建议你用存储过程来替代动态的SQL语句.是否把业务逻辑写到存储过程中,这个有点争议.但是我认为,把业务逻辑写到存储过程里面可以限制返回结果集的大小,减小网络数据的流量,在逻辑层也不用在过滤数据,

WPF 程序中启动和关闭外部.exe程序

当需要在WPF程序启动时,启动另一外部程序(.exe程序)时,可以按照下面的例子来: C#后台代码如下: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; u