BCA
BCA

Reputation: 8506

Why does GridView load so slowly compared to a hardcoded Grid?

I've run into a UX performance issue with UWP's GridView. In my app I need to display 100-200 items in a single view (UI virtualization does not apply here). I'm finding that this GridView takes about 3 seconds to load upon first navigation to the page when compiled for Debug, and 5 seconds for a Release build (I'll save that question for another day!).

My DataTemplate is not overly complex, and I'm using x:Bind and even tried x:Phase, but no significant improvement is found. Then I tried something wacky: I made a plain old Grid and hard-coded the equivalent items and voila--load time is instantaneous. So without getting to technical, I'd guess that using a poor-man's Grid is at least 100x (or 1000x ?) faster than a GridView... to render the same content, using the same data binding.

Just to illustrate the stark contrast in performance between these two approaches, I created the most simple example: starting with this class:

public class Dummy
{
    public int Number { get; set; }
}

... with the following 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>

... and the following code-behind:

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;

I used lazy loading strategy and displayed a ProgressRing upon navigation to the page in question. There are 200 elements, with the simplest possible DataTemplate and model class--and the progress ring displays for 2 seconds (running on a cheap tablet). Already this is unacceptable as far as user experience goes, and this is all we're achieving: DataTemplate screenshot

In contrast, I created another page with the same exact layout and data source, but just constructed the elements by hand, like so:

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

The result? As suspsected, the page loads instantaneously; the ProgressRing doesn't even appear. (This is running on the same cheap tablet.)

So my ultimate question is: is there a way to *drastically * improve the performance of GridView when displaying all elements all at once?

Upvotes: 1

Views: 387

Answers (1)

Kabilan Senapathy
Kabilan Senapathy

Reputation: 134

You can use the async method to add items after the page has been loaded.

Display the page and then load all the grid items asynchronously.

Upvotes: 0

Related Questions