具有许多加载控件的 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 控件

Silverlight是否比JavaScript具有性能优势?

更新后强制浏览器重新加载 Silverlight xap

Telerik 与 Silverlight 的 Infragistics

具有许多用户控件的共享点 webpart

Expression Blend 2 中 Silverlight 控件的设计时渲染