ReactiveUI – 查看定位器性能

在我使用ReactiveUI WPF应用程序中,我注意到一个性能不佳的领域。

我有一个视图模型,其中包含许多其他轻量级视图模型(想想30ish)。 这些嵌套的视图模型很简单,通常每个都代表一个按钮。 它们都显示在用户控件中,在使用ReactiveUI的OneWayBind连接的ItemsControl中。 这意味着使用ViewModelViewHost显示每个项目。

所以,问题

在我强大的桌面PC上,当我导航到这个视图模型时,按下“video模型”按钮和视图变化之间存在明显的延迟,大约0.5秒。 当我在Power-PC上运行相同的软件时,延迟将近4秒。 从UX的角度来看,这是一个非常大的问题。

我学到了什么

我试了很长时间的分析和调试我的代码,发现没有问题的区域。 Zilch(注意: 在VS中使用JustMyCode,因此ReactiveUI没有显示 )。 但是,我确实找到了解决问题的方法。 我没有使用OneWayBind绑定到ItemsControl.ItemSourceOneWayBind在XAML中这样做: ItemSource={Binding MyViewModels}并手动设置DataTemplate 。 这导致更快的转换。

使用ItemsControlOneWayBind绑定时,将自动为您创建ViewModelViewHost ,并使用ViewLocator查找视图模型的视图。 我认为由于某种原因这很慢。

是否有人知道如何在不必手动为ItemsControl定义大量数据模板的情况下解决这个性能问题? 如果我有视图模型的视图模型的视图模型,那么事情会很快变得丑陋。 根据我过去使用Caliburn.Micro经验,视图位置约定很快,所以我也想知道我是不是正确地使用了ReactiveUI ,并且有一种更快的替代方法。

谢谢。

TLDR;

ViewModelViewHost作为DataTemplate个视图模型的DataTemplate导致视图在最初加载时非常缓慢,使UI看起来好像已经崩溃了。 有什么方法可以避免这种情况吗?

我认为这个问题的根本原因是TransitioningContentControl的实现问题。

此控件(其中包含许多现有实现,其中大多数源自Silverlight one AFAICT)将导出内容时导致额外的加载/卸载转换。

导航时,当前控件将触发卸载/加载/卸载,而不是单个卸载。 许多 地方都引用了这个问题。

在RxUI中使用时,此错误会导致在离开View上调用WhenActivated ,从而导致性能问题,尤其是在当前视图很复杂的情况下。

应该重写TransitioningContentControl以避免这种额外的转换, 这是一个不受此问题影响的示例实现。

我以前遇到过这个完全相同的问题。

基本上,你想显示/隐藏,而不是创建/销毁。

创建新的可视树需要做很多工作,切换标签时通常会延迟几秒或更长时间。

现在,如果你创造了一切,然后折叠你不需要的东西并按需显示它,突然一切都在眨眼间更新。

这可能需要一些重构才能做到这一点,代码可能看起来不那么干净,但它肯定会运行得非常快。