使用DynamicResource相比StaticResource会有明显的性能损耗吗?

17

我们的设计师正在使用Blend来为我们的WPF应用程序添加样式。当他为属性选择本地资源时,Blend会将它们应用为{DynamicResource}而不是{StaticResource}。我猜想Blend这么做是因为它使得应用程序在运行时可以重新主题化而无需重启。

我的问题是:这样额外的查找是否有显著的性能代价?我们应该要求设计师回头手动更改那些动态资源到静态资源吗?

这里有一个很好的SO问题,解释了这两种类型之间的区别:What's the difference between StaticResource and DynamicResource in WPF?

3个回答

31

很不幸的是,在这种情况下,直接比较相对性能非常困难,因为任何退化都会在WPF引擎的深处显示出来。在WPF早期,使用StaticResource是推荐的标准性能调整之一,我们在组织中严格遵循并向他人推荐。尽管如此,我仍然感到非常烦恼,因为Blend却采用了DynamicResource,即使这有助于在设计时正确地渲染其他文件中的资源。

随着时间的推移,我的观点发生了变化,这在一定程度上归因于个人经验,也得益于微软Blend团队的反馈。你可能知道,Blend完全使用WPF编写,并具有完整的备用主题(Light),可以在程序运行时动态切换。这是可能的,因为他们在几乎所有的样式中都使用了DynamicResource。据他们表示,这并没有真正引起任何性能问题。考虑到Blend可能是现有最广泛使用的WPF应用程序,我倾向于给予他们的看法更大的权重。

另外要考虑的是DynamicResource的实际用途。能够在运行时更改样式是其中的一部分,但还包括构建资源层次结构时提供的灵活性,这可以使管理共享样式变得更加容易。我相信你已经遇到过这样的情况,在运行时StaticResource引用失败,因为它指向的资源要在层次结构的另一分支中加载。

显然,StaticResource非常适用于指向你知道将在正确时间可用的特定键。当手写XAML时,我仍然倾向于始终使用它。但考虑到让设计师在Blend中生成你的XAML所获得的生产力,任何小的性能增益可能都不值得将所有东西手动维护为Static。


关于您的声明“显然,StaticResource非常有用,可以指向您知道将在正确时间可用的特定键。”这是否意味着DynamicResource失去了编译时类型检查并移动到运行时? - scobi
是的。在大多数情况下,未解析的DynamicResource引用只会获得默认值(例如Brushes的黑色),并等待它正在寻找的关键字出现。编译器实际上没有办法自行验证这种情况。 - John Bowen

6
据说动态资源和静态资源在性能上有所区别,但是否“显著”取决于有多少次动态查找。除非你有成千上万个DynamicResource引用,否则无论如何都不会有明显的差异;如果动态资源的性能比静态资源差得那么多,我想Blend在生成它们时会更加保守。
事实上,在我运行了一个简单的测试后,我发现了一个反直觉的结果,即使用3000个资源引用时,DynamicResource比StaticResource运行速度更快(当我用DynamicResource代替所有内容时,我看到的加载时间约为200毫秒,而StaticResource则约为400毫秒)。
这个测试是不切实际的,原因有很多:所有的引用都指向同一个东西,我在调试器下运行等等。但是这表明,为了以防万一而改变Blend输出的努力可能还为时过早——如果你确实注意到了减速,它可能并不一定是DynamicResource引用的错——一定要进行测量!

1
我认为DynamicResources是在后台线程上加载的,只有当使用它们的项变得可见时才会加载,因此使速度测试非常困难。 - Ian Ringrose

1

不幸的是,如果您将动态资源更改回静态资源,它将破坏 Blend。特别是在使用引用动态资源的 UserControls 时,如果将它们更改为静态,则当在 Blend 中托管在另一个控件内时,该控件将无法呈现。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接