Reputation: 8506
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:
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
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