WPF性能优化 - zLulus/My_Note GitHub Wiki
元素:
减少需要显示的元素数量:去除不需要或者冗余的XAML元素代码;简化templates来减少可视化树的层次
UI虚拟化:只显示当前需要显示的元素
不要把不要显示的自定义控件隐藏在主界面中
冻结可以冻结的控件:通过在代码中调用Freeze()或者在Xmal中设定PresentationOptions:Freeze=”true”来冻结可以冻结的控件。由于这样系统不必监听该控件的变化,所以可以带来性能的提升.
尽可能使用StreamGeometries 代替PathGeometries
尽量多使用Canvas等简单的布局元素:少使用Grid或者StackPanel等复杂的,越复杂性能开销越大
尽量不要使用ScrollBarVisibility=Auto
使用延迟滚动增强用户体验
使用容器回收提高性能
线程
耗时操作放在放在非UI线程(非主线程)上处理,保持UI的顺畅:处理完成后如果需要在UI上展示,调用Dispatcher.BeginInoke()方法
绑定
Mode:关于Data Binding,根据实际情况对Binding指定不同的Mode,性能比较:OneTime>OneWay>TwoWay
修正系统中Binding错误
当我们在列表(比如ListBox)显示了一个CLR对象列表(比如List)时,如果想在修改List对象后,ListBox也动态的反映这种变化。此时,我们应该使用动态的ObservableCollection对象绑定。而不是直接的更新ItemSource。两者的区别在于直接更新ItemSource会使WPF抛弃ListBox已有的所有数据,然后全部重新从List加载。而使用ObservableCollection可以避免这种先全部删除再重载的过程
,效率更高。
资源
通常情况下我们会把样式资源都统一到App.xaml中,这是很好的,便于资源的管理。
尽量把多次重复用到的资源放到App.xaml中。例如某些页面的资源只会在当前页面中使用到,那么可以把资源定义在当前页面; 因为放在控件中会使每个实例都保留一份资源的拷贝。
如非必要,不要使用DynaicResource,使用StaticResource即可
动画
尽量少的使用Animation:程序启动时,Animation渲染时会占用一些CPU资源。
降低动画的帧率:大多数动画不需要高帧率,而系统默认为60frames/sec,所以可以设定Storyboard.DesiredFrameRate 为更低值。
使用卸载事件卸载不必要的动画:动画肯定会占用一定的资源,如果处置方式不当,将会消耗更多的资源,如果你认为它们无用时,你应该考虑如何处理他们,如果不这样做,就要等到可爱的垃圾回收器先生来回收资源。
图像
对Image做动画处理的时候(如调整大小等),可以使用这条语句 RenderOptions.SetBitmapScalingMode(MyImage,BitmapScalingMode.LowQuality),以改善性能。
预测图像绘制能力:根据硬件配置的不同,WPF采用不同的Rendering Tier做渲染。下列情况请特别注意,因为在这些情况下,即使是处于Rendering Tier 2的情况下也不会硬件加速。
文本
文字少的时候用TextBlock或者label,长的时候用FlowDocument.
使用字体缓存服务提高启动时间:WPF应用程序之间可以共享字体数据,它是通过一个叫做PresentationFontCache Service的Windows服务实现的,它会随Windows自动启动。你可以在控制面板的“服务”中找到这个服务(或在“运行”框中输入Services.msc),确保这个服务已经启动。
其他
用NavigationWindow的时候,尽量Update the client area by object,而不是URI
建立逻辑树或者视觉树的时候,遵循Top-Down的原则
使用WPF分析工具分析WPF程序
:分析WPF程序是理解其行为很重要的一步,市场上有大量现成的WPF程序分析工具,如Snoop,WPFPerf,Perforator和Visual Profiler,其中Perforator和Visual Profiler是WPF Performance Suite的一部分,要了解这些工具的用法,请去它们的项目主页。