具有许多加载控件的 Silverlight 性能
Posted
技术标签:
【中文标题】具有许多加载控件的 Silverlight 性能【英文标题】:Silverlight performance with many loaded controls 【发布时间】:2012-04-03 06:00:19 【问题描述】:我有一个带有许多 DataGrid(来自 Silverlight Toolkit)的 SL 应用程序,每个都有自己的视图。如果打开了多个 DataGrid,则在视图(例如 TabItems)之间进行更改需要很长时间(几秒钟),并且会冻结整个应用程序(UI 线程)。
加载的 DataGrid 越多,更改所需的时间就越长。这些减慢 UI 更改的 DataGrids 可能位于应用程序的其他位置,此时甚至不可见。但是一旦它们被打开(并加载了数据),它们显示其他 DataGrid 的速度就会变慢。 请注意,DataGrid 不会被释放然后重新创建,它们仍然保留在内存中,只是它们的父控件被隐藏并再次可见。
我已对应用程序进行了概要分析。说明agcore.dll的SetValue函数是瓶颈。不幸的是,这个负责绘图的 Silverlight 本机库无法使用调试符号。
问题不在于 DataGrid 控件 - 我尝试将其替换为 XCeed 的网格,但更改视图时的性能更差。
你知道如何解决这个问题吗? 为什么更多打开的控件会减慢其他控件的速度?
我创建了一个显示此问题的示例:VS solution、live demo
更新: 在提供的示例上使用 VS11 探查器表明问题可能在于 MeasureOverride 被多次调用(我猜对于每个 DataGridCell)。但是,为什么在其他地方加载更多控件时速度会变慢?有没有办法提高性能?
更新 2: 我应该提一下,我不在我的特定应用程序中使用 TabControl。我使用 Caliburn.Micro 和 ContentControl 来显示当前活动的 ViewModel。但是 TabControl 也有同样的问题,所以我用它来描述核心问题。
【问题讨论】:
查看这里的讨论(关于 TabControl 的部分),它可能会有所帮助:***.com/questions/1389769/… 实际上,在我的原始应用程序中,我使用 Caliburn.Micro(MVVM 框架),所以我有一个 ContentControl 绑定到当前活动的 ViewModel(以及它的 View),而不是 TabControl。不过,我会检查讨论并让你知道。谢谢! @Phil 建议的解决方案在我的情况下不起作用:-( 您是否考虑过将选项卡控件子类化并覆盖 MeasureOverride?span> 您将 CM 用于实际应用,但 PerfTest 没有? 【参考方案1】:我在使用 c1DataGrid 时遇到了这个问题,我发现关闭主题后,更改选项卡很快,并且可以立即进行其他 UI 操作。
也试试:
-
通过 VS 单步执行,确保您的任何代码都不会被调用。
删除所有应用的样式
如果逐个组件消除仍然很慢,可能不仅仅是数据网格
用 c1datagrid 替换您的数据网格
【讨论】:
【参考方案2】:所以,我遵循了创建自定义控件的想法,结果如下:http://www.baud.cz/blog/fast-switching-between-viewmodels-in-caliburn.micro。
MVVM 演示应用程序的快速链接:Original 和 Fixed
【讨论】:
+1。这就是我们最终在一个项目中所做的。我们有相同的设置TabControl
,但失去了视觉效果,我们还使用了 Caliburn。解决方案是使用IViewAware.GetView
缓存并返回缓存的视图
AFAIK,Caliburn.Micro 中的 IViewAware.GetView 已经缓存了视图。我认为可以通过更改 TabControl 中的视图来判断滚动条位置持续存在的位置(这未保存在 VM 中)。【参考方案3】:
这是一个半疯狂的猜测,但我想知道在未选中的选项卡上将 Visibility 设置为 Collapsed 是否会有所帮助。 (我假设 DataGrid 上启用了行虚拟化。这在过去帮助了我很多。)
我的半疯狂猜测主要基于此tip 以及我对找到的here 信息的中间理解。
【讨论】:
我实际上重写了使用 MVVM 提供的示例,并在 ContentControl 中显示活动内容,该内容使用转换器呈现只有一个活动的视图,但仍然很慢。 @Bryant 这正是我的问题。我只是使用 TabControl 来尽可能简化它。我可以看到的可能解决方案是创建一个自定义 ContentControl(可能基于 ItemsControl),除了活动项目之外,它还会以某种方式保存其他视图,以便它们不会从可视树中删除,因此在激活相应视图时不需要再次重新创建它们.【参考方案4】:我们遇到了类似的情况,我们动态加载了许多负载繁重的用户控件,并且呈现的越多,应用程序似乎越慢。听起来很疯狂,当我们将每个控件的布局根设置为 Border 控件时,性能问题显着缓解,因为布局系统不必费力地更新所有资源。
只是想分享一些为我们创造了奇迹的东西,你可以尝试一下。
【讨论】:
以上是关于具有许多加载控件的 Silverlight 性能的主要内容,如果未能解决你的问题,请参考以下文章
Silverlight是否比JavaScript具有性能优势?