与硬编码网格相比,为什么GridView加载速度如此之慢?

时间:2016-01-08 14:29:08

标签: gridview winrt-xaml uwp

我在使用UWP的GridView时遇到了UX性能问题。在我的应用程序中,我需要在单个视图中显示100-200个项目(UI虚拟化不适用于此处)。我发现这个GridView在编译为Debug时首次导航到页面时需要大约3秒钟加载,而发布版本需要5秒钟(我将这个问题保存一天!)。

我的DataTemplate并不过分复杂,我使用x:Bind甚至尝试过x:Phase,但没有找到明显的改进。然后我尝试了一些古怪的东西:我制作了一个普通的旧网格并对相应的项目进行了硬编码,并且加载时间是瞬间完成的。因此,在没有达到技术水平的情况下,我猜测使用穷人的网格比GridView至少快100倍(或1000倍?)来渲染相同的内容,使用相同的数据绑定。

为了说明这两种方法之间的性能形成鲜明对比,我创建了一个最简单的例子:从这个类开始:

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;

我使用了延迟加载策略,并在导航到相关页面时显示了ProgressRing。有200个元素,最简单的DataTemplate和模型类 - 进度环显示2秒(在便宜的平板电脑上运行)。就用户体验而言,这已经是不可接受的了,这就是我们所做的一切: DataTemplate screenshot

相比之下,我创建了另一个具有相同布局和数据源的页面,但只是手工构建了元素,如下所示:

        <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)

结果呢?由于被怀疑,页面立即加载; ProgressRing甚至没有出现。 (这是在同样便宜的平板电脑上运行。)

所以我的最终问题是:有没有办法在一次显示所有元素时*大幅*改善GridView的性能?

1 个答案:

答案 0 :(得分:0)

您可以使用async方法在页面加载后添加项目。

显示页面,然后异步加载所有网格项。