UWP 当ListView嵌套了很多GirdViews(启用一行)时,ListView的性能很差

UWP when many GirdViews(one row enabled) nested in ListView, ListView's performance is very bad

我正在设计一个类似于 Netflix 主页的页面。它有许多 (20+) GirdViews(启用一行)嵌套在外部 ListView 中。所有项目都是不确定的,因此它们必须在 运行 时间生成。 所以我设计如下:

Xaml:

<Page.Resources>
        <DataTemplate x:Key="FirstLevelListViewItemTemplate" x:DataType="model:CategoriesItem">
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition/>
                </Grid.RowDefinitions>

                <TextBlock Text="{x:Bind CategoryName}" FontSize="28"/>

                <GridView
                    Grid.Row="1"
                    Height="200"
                    ScrollViewer.HorizontalScrollBarVisibility="Hidden"
                    ScrollViewer.HorizontalScrollMode="Enabled"
                    ScrollViewer.VerticalScrollMode="Disabled"
                    ItemsSource="{x:Bind categories, Mode=OneWay}">
                    <GridView.ItemsPanel>
                        <ItemsPanelTemplate>
                            <ItemsWrapGrid Orientation="Vertical"/>
                        </ItemsPanelTemplate>
                    </GridView.ItemsPanel>
                    <GridView.ItemTemplate>
                        <DataTemplate x:DataType="model:CategoryItem">
                            <controls:ImageEx IsCacheEnabled="True" Width="250" Source="{x:Bind cover_image_url}"/>
                        </DataTemplate>
                    </GridView.ItemTemplate>
                </GridView>
            </Grid>
        </DataTemplate>
    </Page.Resources>

    <!--<ScrollViewer>-->
        <ListView x:Name="list"
                    SelectionMode="None"
                    ItemTemplate="{StaticResource FirstLevelListViewItemTemplate}">
    <!--Disable ListView UI virtualization-->
    <ListView.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel/>
        </ItemsPanelTemplate>
    </ListView.ItemsPanel>
        </ListView>
    <!--</ScrollViewer>-->

模型文件:

public class CategoriesItem
{
    public string CategoryName { get; set; }
    public List<CategoryItem> categories { get; set; }
}

public class CategoryItem
{
    public string cover_image_url { get; set; }
}

.cs 文件

用于从本地加载数据:

list.ItemsSource = await GetData();

所以

场景 1:

运行 启用了 ListView 的 UI 虚拟化的应用程序,绑定过程非常快,内存约为 300MB。然后用鼠标快速滚动up/downListView,ListView上下滚动很慢,黑屏后显示数据很慢。

场景 2:

运行 app with ListView's UI virtualization disabled, 这次bind过程耗时很长,内存可能升到1GB。但是快速滚动up/downListView,就OK了。

我的需求:

如何修复?

如何解决这个问题,非常感谢。

I want the live visual tree shows all the ListViewItems, because I will use all the ListViewItems to do some extra things.

为了解释这种行为,我们可以参考 UI virtualization,UI 虚拟化是您可以做出的最重要的改进。

This means that UI elements representing the items are created on demand. For an items control bound to a 1000-item collection, it would be a waste of resources to create the UI for all the items at the same time, because they can't all be displayed at the same time. ListView and GridView (and other standard ItemsControl-derived controls) perform UI virtualization for you. When items are close to being scrolled into view (a few pages away), the framework generates the UI for the items and caches them. When it's unlikely that the items will be shown again, the framework re-claims the memory.

您可以通过将 ItemsPanelTemplate 更改为 StackPanel

来关闭它
<ListView>
    <ListView.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel />

        </ItemsPanelTemplate>
    </ListView.ItemsPanel>
</ListView>

Bind process quick and memory low.

您可以进行数据虚拟化,将 json 数据切割成切片,然后使用 ListView LoadMoreItemsAsync 加载更多数据。