WPF 性能优化 14 点

建立漂亮 UI 时需要关注应用程序的性能,WPF 尤其如此。以下是从 MS 文档中总结出的一些关键的性能优化点,实际编写中可备参考。

1、建立逻辑树时,尽量考虑从父结点到子结点的顺序构建。因为当逻辑树的一个结点发生变化时(比如添加或删除),它的父结点和所有的子结点都会激发 Invalidation。程序应该避免不必要的 Invalidation。

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

3、在使用数据绑定的过程中,绑定实现的机制不同,绑定的效率也不同:

  • A、数据源是一个 CLR 对象,属性也是一个 CLR 属性。对象通过 TypeDescriptor / PropertyChanged 模式实现通知功能。此时绑定引擎用 TypeDescriptor 来反射源对象,效率最低。
  • B、数据源是一个 CLR 对象,属性也是一个 CLR 属性。对象通过 INotifyPropertyChanged 实现通知功能。此时绑定引擎直接反射源对象,效率稍微提高。
  • C、数据源是一个 DependencyObject,而且属性是一个 DependencyProperty。此时不需要反射,直接绑定,效率最高。

4、访问 CLR 对象和 CLR 属性的效率会比访问 DependencyObject / DependencyProperty 高,注意这里指的是访问,不要和前面的绑定混淆;但把属性注册为 DependencyProperty 会有很多的优点,比如继承、数据绑定和 Style。另外,因注册的 DependencyProperty 默认不可继承,则继承特性也会降低 DependencyProperty 值刷新的效率。注册 DependencyProperty 属性时,应该把 DefaultValue 传递给Register 方法的参数来实现默认值的设置,而不是在构造函数中设置。

5、使用元素 TextFlow 和 TextBlock 时,若不需要 TextFlow 的某些特性,就应该考虑使用效率更高的 TextBlock。

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

7、在 TextFlow 中使用 UIElement(比如 TextBlock)所需的代价要比使用 TextElement(比如 Run)的代价高。

8、把 Label(标签)元素的 ContentProperty 和一个字符串(String)绑定的效率要比把字符串和 TextBlock 的 Text 属性绑定的效率低。因为 Label 在更新字符串时会丢弃原来的字符串,全部重新显示内容。

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

10、显示超链接时尽量只在 IsMouseOver 为 True 的时候显示下划线,一直显示下划线的代价相比较要高很多。

11、在自定义控件时,尽量不要在控件的 ResourceDictionary 定义资源,而应该放在 Window 或者 Application 级。因为放在控件中会使每个实例都保留一份资源的拷贝。

12、如果多个元素使用相同的 Brush 时,应该考虑在资源定义 Brush,让他们共享一个 Brush 实例。

13、若需修改元素的 Opacity 属性,应使用一个有同样效果的 Brush  来填充元素。因为直接修改元素的 Opacity 会迫使系统创建一个临时的 Surface。

14、在系统中使用大型的 3D Surface 时,若不需要 Surface 的 HitTest 功能就关闭之。因为默认的 HitTest 会占用大量的 CPU 时间进行计算。UIElement 有 IsHitTestVisible 属性可以用来关闭 HitTest 功能。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值