为什么GridView的加载速度比硬编码的网格慢?
我在UWP的GridView中遇到了UX性能问题。在我的应用程序中,我需要在单个视图中显示100-200个项目(此处不适用UI虚拟化)。我发现这个GridView在编译调试时第一次导航到页面时大约需要3秒加载,而发布版本则需要5秒加载(我将把这个问题留到下一天!) 我的数据模板并不太复杂,我正在使用x:Bind,甚至尝试了x:Phase,但没有发现显著的改进。然后我尝试了一些古怪的东西:我制作了一个简单的旧网格,并对等价的项进行了硬编码,瞧,加载时间是瞬时的。所以在不涉及技术的情况下,我想使用穷人的网格至少比GridView快100倍(或1000倍?)。。。使用相同的数据绑定呈现相同的内容 为了说明这两种方法在性能上的鲜明对比,我创建了一个最简单的示例:从这个类开始:为什么GridView的加载速度比硬编码的网格慢?,gridview,winrt-xaml,uwp,Gridview,Winrt Xaml,Uwp,我在UWP的GridView中遇到了UX性能问题。在我的应用程序中,我需要在单个视图中显示100-200个项目(此处不适用UI虚拟化)。我发现这个GridView在编译调试时第一次导航到页面时大约需要3秒加载,而发布版本则需要5秒加载(我将把这个问题留到下一天!) 我的数据模板并不太复杂,我正在使用x:Bind,甚至尝试了x:Phase,但没有发现显著的改进。然后我尝试了一些古怪的东西:我制作了一个简单的旧网格,并对等价的项进行了硬编码,瞧,加载时间是瞬时的。所以在不涉及技术的情况下,我想使用穷
public class Dummy
{
public int Number { get; set; }
}
。。。使用以下XAML:
<GridView Name="LazyContent" x:DeferLoadStrategy="Lazy" ItemsSource="{x:Bind Dummies}" >
<GridView.ItemTemplate>
<DataTemplate x:DataType="local:Dummy">
<Border>
<TextBlock Text="{x:Bind Number}" />
</Border>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
。。。以及以下隐藏代码:
public List<Dummy> Dummies { get; set; }
(in constructor)
List<Dummy> temp = new List<Dummy>();
for (int i = 0; i < 200; i++)
temp.Add(new Dummy() { Number = i });
Dummies = temp;
公共列表假人{get;set;}
(在构造函数中)
列表温度=新列表();
对于(int i=0;i<200;i++)
临时添加(新虚拟(){Number=i});
假人=温度;
我使用了延迟加载策略,并在导航到相关页面时显示了ProgressRing。有200个元素,使用最简单的DataTemplate和model类,progress ring显示2秒钟(在廉价平板电脑上运行)。就用户体验而言,这已经是不可接受的,这就是我们正在实现的全部目标:
相比之下,我创建了另一个具有相同精确布局和数据源的页面,但只是手工构建元素,如下所示:
<Grid Name="LazyContent" x:DeferLoadStrategy="Lazy" >
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid Grid.Row="0" Grid.Column="0" >
<TextBlock Text="{x:Bind Dummies[0].Number}" />
</Grid>
<Grid Grid.Row="0" Grid.Column="1" >
<TextBlock Text="{x:Bind Dummies[1].Number}" />
</Grid>
<Grid Grid.Row="0" Grid.Column="2" >
<TextBlock Text="{x:Bind Dummies[2].Number}" />
</Grid>
<Grid Grid.Row="0" Grid.Column="3" >
<TextBlock Text="{x:Bind Dummies[3].Number}" />
</Grid>
... you get the idea (repeat another ~200 times)
... 你明白了(再重复200次)
结果如何?暂停时,页面会立即加载;ProgressRing甚至没有出现。(这是在同一款廉价平板电脑上运行的。)
所以我的最终问题是:当一次显示所有元素时,有没有办法*彻底*提高GridView的性能 加载页面后,可以使用async方法添加项目
显示页面,然后异步加载所有网格项目。加载页面后,可以使用异步方法添加项目
显示页面,然后异步加载所有网格项。我很好奇您的
ProgressRing
绑定到的IsActive
标志是什么?我只是在调用FindName(“LazyContent”)之前在后面的代码中设置IsActive要触发GridView的加载,请记住,GridView
控件本身比Grid
复杂得多。虽然同一个GridView
会在我的开发机器上即时加载,但一次加载数百个项目从来都不是一个好主意。我会使用反应式扩展来加载,比如说,一次加载20个项目,时间跨度100ms
。使用这种方法,您甚至可以通过应用不透明和向上滑动动画来实现更好的用户体验。@JustinXL,谢谢——我试用了您的方法。不幸的是,这会导致更糟糕的情况:GridView甚至无法跟上100毫秒的间隔,并使系统陷入困境,以至于页面上的其他集合元素无法正确加载。在一天结束时,我最初的问题是:为什么所有这些交错加载的工作环境一开始都是必要的?这不像我通过拨号网络加载项目;一切都在内存中,一切都非常简单。我很好奇您的ProgressRing
绑定的IsActive
标志是什么?我只是在调用FindName(“LazyContent”)之前在后面的代码中设置了IsActive要触发GridView的加载,请记住,GridView
控件本身比Grid
复杂得多。虽然同一个GridView
会在我的开发机器上即时加载,但一次加载数百个项目从来都不是一个好主意。我会使用反应式扩展来加载,比如说,一次加载20个项目,时间跨度100ms
。使用这种方法,您甚至可以通过应用不透明和向上滑动动画来实现更好的用户体验。@JustinXL,谢谢——我试用了您的方法。不幸的是,这会导致更糟糕的情况:GridView甚至无法跟上100毫秒的间隔,并使系统陷入困境,以至于页面上的其他集合元素无法正确加载。在一天结束时,我最初的问题是:为什么所有这些交错加载的工作环境一开始都是必要的?这不像我通过拨号网络加载项目;一切都在记忆中,一切都非常简单。是的,这就是我在做的酷。。。快乐发展:)是的,这就是我在做的酷。。。快乐发展:)