Is there a significant performance cost to DynamicResource instead of StaticResource?
Our designer is using Blend to style our WPF application. When he chooses local resources for properties, Blend will apply them as a {DynamicResource}
instead of a {StaticResource}
. My guess is that Blend does this because it enables the app to be re-themed at runtime without having to restart it.
My question is: is there a significant performance cost to this additional lookup? Should we ask the designer to go back and manually change those Dynamics to Statics?
Here is a great SO question that explains the difference between the types: What's the difference bet开发者_如何学JAVAween StaticResource and DynamicResource in WPF?
Unfortunately this is a case where it's very hard to do a direct comparison of the relative performance since the place where any degradation would show up is deep in the WPF engine. In the early days of WPF the use of StaticResource was one of the standard performance tuning changes that was recommended and we tended to follow it pretty strictly in our organization and recommend it to others. I was really annoyed that Blend did Dynamic everything even though that helped it to render resources from other files properly at design time.
Over time my view on this has changed, due somewhat to personal experience, but also feedback from people on the Blend team at Microsoft. As you are probably aware, Blend is written completely in WPF and has a complete alternate theme (Light) that can be switched on the fly while the application is running. This is possible because they used DynamicResource for pretty much all of their styling. According to them, this didn't really cause them any real perf issues. Given that Blend is probably the most widely used WPF application in existence, I tend to give significant weight to their views.
The other thing to consider is DynamicResource's actual usefulness. The ability to change styling on the fly is one part of it, but also the flexibility it gives you in building your Resource hierarchy can make it a lot easier to manage shared styles. I'm sure you've run into a situation where a StaticResource reference blew up at runtime because the resource it pointed to was to be loaded in a different branch of the hierarchy.
Obviously StaticResource is very useful for pointing to a specific key that you know is going to be available at the right time. When hand-writing XAML I still tend to use it all the time. But given the productivity you gain out of having a designer generate your XAML in Blend, any small performance gain you might get is probably not worth the overhead of hand-maintaining everything as Static.
There is said to be a performance difference, but whether it is "significant" will depend on how many dynamic lookups are happening. Unless you have thousands of DynamicResource references it's probably not going to be noticeable either way; if dynamic resources performed that much worse than static ones, I suspect Blend would be more conservative about generating them.
In fact, when I ran a naive test, I found the counterintuitive result that DynamicResource ran faster than StaticResource (with 3000 resource references, I saw load times around 200ms when I used DynamicResource for everything vs. around 400ms for StaticResource).
This was an unrealistic test for numerous reasons: all the references were to the same thing, I was running under the debugger, etc. etc. But it suggests it would be premature to put effort into changing the Blend output "just in case" -- and that if you do notice a slowdown it may not necessarily be the fault of the DynamicResource references -- always measure!
Unfortunately if you change the dynamic resources back to statics, it will break Blend. This seems to be true especially when using UserControls that reference dynamic resources, if you change them to static the control will not render when hosted inside another control in Blend.
精彩评论