maui icon indicating copy to clipboard operation
maui copied to clipboard

CollectionView within a CollectionView is very slow when loading items

Open IeuanWalker opened this issue 3 years ago • 9 comments
trafficstars

Description

CollectionView within a CollectionView is very slow when loading items

https://user-images.githubusercontent.com/6544051/170470317-e2fed6cc-86bf-4874-bd11-bdcddb4648b4.mp4

Steps to Reproduce

<ContentPage x:Class="FitNote.Pages.HomePage"
             xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:db="clr-namespace:FitNote.DatabaseModels;assembly=FitNote.DatabaseModels"
             xmlns:mct="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
             xmlns:models="clr-namespace:FitNote.Models"
             xmlns:vm="clr-namespace:FitNote.ViewModels"
             x:DataType="vm:HomeViewModel"
             BackgroundColor="{DynamicResource BackgroundColourPrimary}"
             NavigationPage.HasNavigationBar="false">
    <ContentPage.Resources>
        <ResourceDictionary>
            <mct:IsNotNullConverter x:Key="IsNotNullConverter" />
            <mct:IsEqualConverter x:Key="IsEqualConverter" />
        </ResourceDictionary>
    </ContentPage.Resources>
    <ContentPage.Content>
        <Grid RowDefinitions="*,auto">
            <ScrollView x:Name="sc" Grid.Row="0">
                <VerticalStackLayout>
                    <Border Grid.Column="0"
                            Margin="0"
                            Padding="0"
                            BackgroundColor="{DynamicResource BackgroundColourSecondary}"
                            HeightRequest="230"
                            Stroke="{DynamicResource BackgroundColourSecondary}"
                            StrokeThickness="0">
                        <Border.StrokeShape>
                            <RoundRectangle CornerRadius="0,0,20,20" />
                        </Border.StrokeShape>
                        <VerticalStackLayout Padding="0,30,0,0" Spacing="0">
                            <Label Margin="0,0,20,0"
                                   FontFamily="LASolid"
                                   FontSize="30"
                                   HorizontalOptions="End"
                                   Text="&#xf013;"
                                   TextColor="{DynamicResource TextColourPrimary}">
                                <Label.GestureRecognizers>
                                    <TapGestureRecognizer Tapped="OnSettings_Tapped" />
                                </Label.GestureRecognizers>
                            </Label>

                            <Label Margin="25,5,0,15"
                                   FontAttributes="Bold"
                                   FontSize="20"
                                   Text="{Binding SelectedDiary.Date, StringFormat='{0:MMMM yyyy}'}"
                                   TextColor="{DynamicResource TextColourPrimary}" />
                            <CollectionView FlowDirection="RightToLeft"
                                            ItemSizingStrategy="MeasureFirstItem"
                                            ItemsLayout="HorizontalList"
                                            ItemsSource="{Binding Dates}"
                                            SelectedItem="{Binding SelectedDiary}"
                                            SelectionMode="Single">
                                <CollectionView.ItemTemplate>
                                    <DataTemplate>
                                        <Grid Padding="10"
                                              x:DataType="models:DiaryHomePageModel"
                                              BackgroundColor="Transparent"
                                              RowDefinitions="70, 30">
                                            <Border Grid.Row="0"
                                                    Padding="0"
                                                    BackgroundColor="{DynamicResource BlueLightColour}"
                                                    HeightRequest="70"
                                                    Stroke="Transparent"
                                                    StrokeThickness="5">
                                                <Border.StrokeShape>
                                                    <RoundRectangle CornerRadius="200" />
                                                </Border.StrokeShape>
                                                <Border.Triggers>
                                                    <DataTrigger Binding="{Binding IsSelected}"
                                                                 TargetType="Border"
                                                                 Value="true">
                                                        <Setter Property="BackgroundColor" Value="{DynamicResource PurpleLightColour}" />
                                                        <Setter Property="Stroke" Value="{DynamicResource PurpleDarkColour}" />
                                                    </DataTrigger>
                                                </Border.Triggers>
                                                <VerticalStackLayout Padding="10">
                                                    <Label HorizontalTextAlignment="Center"
                                                           Text="{Binding DayOfTheWeekLetter}"
                                                           TextColor="{DynamicResource BlueDarkColour}" />
                                                    <Label HorizontalTextAlignment="Center"
                                                           Text="{Binding Date, StringFormat='{0:dd}'}"
                                                           TextColor="Black" />
                                                </VerticalStackLayout>
                                            </Border>
                                            <Ellipse Grid.Row="1"
                                                     Margin="0,10"
                                                     Fill="Transparent"
                                                     HeightRequest="10"
                                                     WidthRequest="10">
                                                <Ellipse.Triggers>
                                                    <DataTrigger Binding="{Binding IsSelected}"
                                                                 TargetType="Ellipse"
                                                                 Value="true">
                                                        <Setter Property="Fill" Value="#4E16FF" />
                                                    </DataTrigger>
                                                </Ellipse.Triggers>
                                            </Ellipse>
                                            <VisualStateManager.VisualStateGroups>
                                                <VisualStateGroupList>
                                                    <VisualStateGroup x:Name="CommonStates">
                                                        <VisualState x:Name="Normal" />
                                                        <VisualState x:Name="Selected">
                                                            <VisualState.Setters>
                                                                <Setter Property="BackgroundColor" Value="Transparent" />
                                                            </VisualState.Setters>
                                                        </VisualState>
                                                    </VisualStateGroup>
                                                </VisualStateGroupList>
                                            </VisualStateManager.VisualStateGroups>
                                        </Grid>
                                    </DataTemplate>
                                </CollectionView.ItemTemplate>
                            </CollectionView>
                        </VerticalStackLayout>
                    </Border>
                    <Grid Margin="0,20" ColumnDefinitions="*,3,*">
                        <Label Grid.Column="0" HorizontalOptions="Center">
                            <Label.FormattedText>
                                <FormattedString>
                                    <FormattedString.Spans>
                                        <Span FontFamily="LASolid"
                                              FontSize="20"
                                              Text="&#xf2f2;"
                                              TextColor="{DynamicResource TextColourPrimary}" />
                                        <Span FontSize="15"
                                              Text="12m"
                                              TextColor="{DynamicResource TextColourPrimary}" />
                                    </FormattedString.Spans>
                                </FormattedString>
                            </Label.FormattedText>
                        </Label>

                        <BoxView Grid.Column="1"
                                 BackgroundColor="{DynamicResource BackgroundColourSecondary}"
                                 CornerRadius="1.5"
                                 IsVisible="{Binding SelectedDiary.TotalWeight, Converter={StaticResource IsNotNullConverter}}"
                                 WidthRequest="3" />

                        <Label Grid.Column="2"
                               HorizontalOptions="Center"
                               IsVisible="{Binding SelectedDiary.TotalWeight, Converter={StaticResource IsNotNullConverter}}">
                            <Label.FormattedText>
                                <FormattedString>
                                    <FormattedString.Spans>
                                        <Span FontFamily="LASolid"
                                              FontSize="20"
                                              Text="&#xf44b;"
                                              TextColor="{DynamicResource TextColourPrimary}" />
                                        <Span FontSize="15"
                                              Text="{Binding SelectedDiary.TotalWeight, StringFormat='{0}Kg'}"
                                              TextColor="{DynamicResource TextColourPrimary}" />
                                    </FormattedString.Spans>
                                </FormattedString>
                            </Label.FormattedText>
                        </Label>
                    </Grid>

                    <CollectionView Grid.Column="2"
                                    Margin="15,0,15,80"
                                    ItemsSource="{Binding SelectedDiary.GroupedWorkouts}"
                                    SelectionMode="None">

                        <CollectionView.EmptyView>
                            <Label FontSize="30"
                                   HorizontalTextAlignment="Center"
                                   Text="No logs" />
                        </CollectionView.EmptyView>
                        <CollectionView.ItemTemplate>
                            <DataTemplate>
                                <Frame Margin="10,0,10,10"
                                       x:DataType="models:GroupedWorkoutsModel"
                                       BackgroundColor="{DynamicResource BackgroundColourSecondary}"
                                       CornerRadius="10"
                                       HasShadow="False">
                                    <VerticalStackLayout>
                                        <Label FontSize="20"
                                               Text="{Binding Key}"
                                               TextColor="{DynamicResource TextColourPrimary}" />
                                        <Label Margin="0,0,00,10"
                                               Text="Back, Chest"
                                               TextColor="{DynamicResource TextColourSecondary}" />

                                        <BoxView BackgroundColor="{DynamicResource BackgroundColourPrimary}"
                                                 CornerRadius="1"
                                                 HeightRequest="2" />

                                        <CollectionView ItemsSource="{Binding Items}">
                                            <CollectionView.ItemTemplate>
                                                <DataTemplate x:DataType="db:LogTbl">
                                                    <Label>
                                                        <Label.FormattedText>
                                                            <FormattedString>
                                                                <FormattedString.Spans>
                                                                    <Span Text="{Binding Weight}" TextColor="{DynamicResource TextColourPrimary}" />
                                                                    <Span Text=" kg" TextColor="{DynamicResource TextColourPrimary}" />
                                                                    <Span Text="{Binding Reps}" TextColor="{DynamicResource TextColourPrimary}" />
                                                                    <Span Text=" reps" TextColor="{DynamicResource TextColourPrimary}" />
                                                                </FormattedString.Spans>
                                                            </FormattedString>
                                                        </Label.FormattedText>
                                                    </Label>
                                                </DataTemplate>
                                            </CollectionView.ItemTemplate>
                                        </CollectionView>
                                    </VerticalStackLayout>
                                </Frame>
                            </DataTemplate>
                        </CollectionView.ItemTemplate>
                    </CollectionView>
                </VerticalStackLayout>
            </ScrollView>

            <Border Grid.Row="0"
                    Margin="20"
                    Padding="0"
                    HeightRequest="50"
                    HorizontalOptions="Center"
                    Stroke="Transparent"
                    StrokeThickness="5"
                    VerticalOptions="End">
                <Border.StrokeShape>
                    <RoundRectangle CornerRadius="30" />
                </Border.StrokeShape>
                <Border.Background>
                    <LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
                        <GradientStop Offset="0.0" Color="#0ED473" />
                        <GradientStop Offset="1.0" Color="#17CC54" />
                    </LinearGradientBrush>
                </Border.Background>
                <Border.Shadow>
                    <Shadow Brush="#0ED473"
                            Opacity="0.5"
                            Radius="70"
                            Offset="0,0" />
                </Border.Shadow>
                <HorizontalStackLayout>

                    <Label Grid.Column="1"
                           Margin="10"
                           FontFamily="LASolid"
                           FontSize="30"
                           HeightRequest="30"
                           HorizontalTextAlignment="Center"
                           Text="&#xf04b;"
                           TextColor="White"
                           WidthRequest="50" />
                    <Label Grid.Column="1"
                           Margin="10"
                           FontFamily="LASolid"
                           FontSize="30"
                           HeightRequest="30"
                           HorizontalTextAlignment="Center"
                           Text="&#xf067;"
                           TextColor="White"
                           WidthRequest="50">
                        <Label.GestureRecognizers>
                            <TapGestureRecognizer Tapped="AddExcersie_Tapped" />
                        </Label.GestureRecognizers>
                    </Label>
                </HorizontalStackLayout>
            </Border>
            <Grid Grid.Row="1"
                  BackgroundColor="{DynamicResource BackgroundColourSecondary}"
                  ColumnDefinitions="*,*"
                  HeightRequest="75">
                <Grid.Shadow>
                    <Shadow Brush="#cdd2e6"
                            Opacity="1"
                            Radius="100"
                            Offset="0,0" />
                </Grid.Shadow>
                <Label Grid.Column="0"
                       FontFamily="LASolid"
                       FontSize="30"
                       HorizontalTextAlignment="Center"
                       Text="&#xf46d;"
                       TextColor="{DynamicResource TextColourPrimary}"
                       VerticalTextAlignment="Center" />
                <Label Grid.Column="1"
                       FontFamily="LASolid"
                       FontSize="30"
                       HorizontalTextAlignment="Center"
                       Text="&#xf1fe;"
                       TextColor="{DynamicResource TextColourPrimary}"
                       VerticalTextAlignment="Center" />
            </Grid>
        </Grid>
    </ContentPage.Content>
</ContentPage>

Version with bug

6.0 (current)

Last version that worked well

Unknown/Other

Affected platforms

Android, I was not able test on other platforms

Affected platform versions

android 11

Did you find any workaround?

No response

Relevant log output

No response

IeuanWalker avatar May 26 '22 10:05 IeuanWalker

Don't use a CollectionView inside an ItemTemplate. Too expensive to create multiple collection views (one per item).

Instead, inside an ItemTemplate, use a VerticalStackLayout with a BindableLayout.

ToolmakerSteve avatar May 31 '22 04:05 ToolmakerSteve

@ToolmakerSteve Was using VerticalStackLayout originally but getting the same performance issue

IeuanWalker avatar May 31 '22 08:05 IeuanWalker

Just for the record, this is the VisualTree - image

Removing the highlighted VericalStackLayout (BindableLayout) and Labels, the performance is fine.

IeuanWalker avatar Jun 01 '22 18:06 IeuanWalker

repro with vs main build(32606.310.main), here is a nested CollectionView example: MauiApp7494.zip

VincentBu avatar Jun 07 '22 06:06 VincentBu

@ToolmakerSteve : is there any other way to have a virtualized horizontal list view in a DataTemplate than the CollectionView?

kasimier-vireq avatar Jun 07 '22 10:06 kasimier-vireq

I believe this is because you have the CollectionView as a child of a VerticalStackLayout.

If this is the case, then what is happening is that ALL the items are being rendered as the VSL expands to contain all the children, and so does the CV. In the end, everything is loaded.

One way to test is to set a WidthRequest/HeightRequest on the CVs to say 200 and see if this improves. If this is the case, then the layout may need to change a bit so that the CV is maybe in a Grid instead and that will prevent it from growing as Grids only expand to the size of the container - unless they are forced to go bigger.

@jonathanpeppers I know you did a huge amount of work in this area and found all sorts of reasons CV load all items.

mattleibow avatar Nov 10 '22 21:11 mattleibow

Hi @IeuanWalker. We have added the "s/needs-info" label to this issue, which indicates that we have an open question for you before we can take further action. This issue will be closed automatically in 7 days if we do not hear back from you by then - please feel free to re-open it if you come back to this issue after that time.

ghost avatar Nov 10 '22 21:11 ghost

I think you could also set a HeightRequest (if it's vertical scrolling) to restrict the height of the CollectionView.

jonathanpeppers avatar Nov 10 '22 22:11 jonathanpeppers

@mattleibow I updated the layout to remove all the VerticalStackLayouts, and the performance didn't change

@jonathanpeppers setting the height request on just the inner collection view didn't change anything. But setting it on the outer collection view did improve it (when set to 100, but setting it to 600 still had performance issues).

Also setting the height is really a solution as it breaks how the UI works.

Removing the inner collectionView solves the perfornamce issue, but again not really a solution.

This is the updated XAML -

<pages:BasePageTemplate x:Class="FitNote.Pages.HomePage"
                        xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
                        xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                        xmlns:databaseModels="clr-namespace:FitNote.Database.Models"
                        xmlns:mct="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
                        xmlns:models="clr-namespace:FitNote.Models"
                        xmlns:pages="clr-namespace:FitNote.Pages"
                        xmlns:vm="clr-namespace:FitNote.ViewModels"
                        x:DataType="vm:HomeViewModel">
    <pages:BasePageTemplate.Resources>
        <ResourceDictionary>
            <mct:IsNotNullConverter x:Key="IsNotNullConverter" />
            <mct:IsEqualConverter x:Key="IsEqualConverter" />
        </ResourceDictionary>
    </pages:BasePageTemplate.Resources>
    <pages:BasePageTemplate.Content>
        <Grid RowDefinitions="*,auto">
            <ScrollView Grid.Row="0">
                <Grid RowDefinitions="230, 65, *">
                    <!-- Dates -->
                    <Border Grid.Row="0"
                            Margin="-2"
                            Padding="0"
                            BackgroundColor="{DynamicResource BackgroundColourSecondary}"
                            HeightRequest="230"
                            Stroke="{DynamicResource BackgroundColourSecondary}"
                            StrokeThickness="0">
                        <Border.StrokeShape>
                            <RoundRectangle CornerRadius="0,0,20,20" />
                        </Border.StrokeShape>
                        <VerticalStackLayout Padding="0,30,0,0" Spacing="0">
                            <Label Margin="0,0,20,0"
                                   FontFamily="LASolid"
                                   FontSize="30"
                                   HorizontalOptions="End"
                                   Text="&#xf013;"
                                   TextColor="{DynamicResource TextColourPrimary}">
                                <Label.GestureRecognizers>
                                    <TapGestureRecognizer Tapped="OnSettings_Tapped" />
                                </Label.GestureRecognizers>
                            </Label>

                            <Label Margin="25,5,0,15"
                                   FontAttributes="Bold"
                                   FontSize="20"
                                   Text="{Binding SelectedDiary.Date, StringFormat='{0:MMMM yyyy}'}"
                                   TextColor="{DynamicResource TextColourPrimary}" />
                            <CollectionView FlowDirection="RightToLeft"
                                            ItemSizingStrategy="MeasureFirstItem"
                                            ItemsLayout="HorizontalList"
                                            ItemsSource="{Binding Dates}"
                                            SelectedItem="{Binding SelectedDiary}"
                                            SelectionMode="Single">
                                <CollectionView.ItemTemplate>
                                    <DataTemplate>
                                        <Grid Padding="10"
                                              x:DataType="models:DiaryHomePageModel"
                                              BackgroundColor="Transparent"
                                              RowDefinitions="70, 30">
                                            <Border Grid.Row="0"
                                                    Padding="0"
                                                    BackgroundColor="{DynamicResource BlueLightColour}"
                                                    HeightRequest="70"
                                                    Stroke="Transparent"
                                                    StrokeThickness="5">
                                                <Border.StrokeShape>
                                                    <RoundRectangle CornerRadius="200" />
                                                </Border.StrokeShape>
                                                <Border.Triggers>
                                                    <DataTrigger Binding="{Binding IsSelected}"
                                                                 TargetType="Border"
                                                                 Value="true">
                                                        <Setter Property="BackgroundColor" Value="{DynamicResource PurpleLightColour}" />
                                                        <Setter Property="Stroke" Value="{DynamicResource PurpleDarkColour}" />
                                                    </DataTrigger>
                                                </Border.Triggers>
                                                <VerticalStackLayout Padding="10">
                                                    <Label HorizontalTextAlignment="Center"
                                                           Text="{Binding DayOfTheWeekLetter}"
                                                           TextColor="{DynamicResource BlueDarkColour}" />
                                                    <Label HorizontalTextAlignment="Center"
                                                           Text="{Binding Date, StringFormat='{0:dd}'}"
                                                           TextColor="Black" />
                                                </VerticalStackLayout>
                                            </Border>
                                            <Ellipse Grid.Row="1"
                                                     Margin="0,10"
                                                     Fill="Transparent"
                                                     HeightRequest="10"
                                                     WidthRequest="10">
                                                <Ellipse.Triggers>
                                                    <DataTrigger Binding="{Binding IsSelected}"
                                                                 TargetType="Ellipse"
                                                                 Value="true">
                                                        <Setter Property="Fill" Value="#4E16FF" />
                                                    </DataTrigger>
                                                </Ellipse.Triggers>
                                            </Ellipse>
                                            <VisualStateManager.VisualStateGroups>
                                                <VisualStateGroupList>
                                                    <VisualStateGroup x:Name="CommonStates">
                                                        <VisualState x:Name="Normal" />
                                                        <VisualState x:Name="Selected">
                                                            <VisualState.Setters>
                                                                <Setter Property="BackgroundColor" Value="Transparent" />
                                                            </VisualState.Setters>
                                                        </VisualState>
                                                    </VisualStateGroup>
                                                </VisualStateGroupList>
                                            </VisualStateManager.VisualStateGroups>
                                        </Grid>
                                    </DataTemplate>
                                </CollectionView.ItemTemplate>
                            </CollectionView>
                        </VerticalStackLayout>
                    </Border>

                    <!-- Workout time and total weight -->
                    <Grid Grid.Row="1"
                          Margin="0,20"
                          ColumnDefinitions="*,3,*"
                          HeightRequest="65">
                        <Label Grid.Column="0"
                               HorizontalOptions="Center"
                               VerticalTextAlignment="Center">
                            <Label.FormattedText>
                                <FormattedString>
                                    <FormattedString.Spans>
                                        <Span FontFamily="LASolid"
                                              FontSize="20"
                                              Text="&#xf2f2;"
                                              TextColor="{DynamicResource TextColourPrimary}" />
                                        <Span FontSize="15"
                                              Text="12m"
                                              TextColor="{DynamicResource TextColourPrimary}" />
                                    </FormattedString.Spans>
                                </FormattedString>
                            </Label.FormattedText>
                        </Label>

                        <BoxView Grid.Column="1"
                                 BackgroundColor="{DynamicResource BackgroundColourSecondary}"
                                 CornerRadius="1.5"
                                 HeightRequest="35"
                                 IsVisible="{Binding SelectedDiary.TotalWeight, Converter={StaticResource IsNotNullConverter}}"
                                 WidthRequest="3" />

                        <Label Grid.Column="2"
                               HorizontalOptions="Center"
                               IsVisible="{Binding SelectedDiary.TotalWeight, Converter={StaticResource IsNotNullConverter}}"
                               VerticalTextAlignment="Center">
                            <Label.FormattedText>
                                <FormattedString>
                                    <FormattedString.Spans>
                                        <Span FontFamily="LASolid"
                                              FontSize="20"
                                              Text="&#xf44b;"
                                              TextColor="{DynamicResource TextColourPrimary}" />
                                        <Span FontSize="15"
                                              Text="{Binding SelectedDiary.TotalWeight, StringFormat='{0}Kg'}"
                                              TextColor="{DynamicResource TextColourPrimary}" />
                                    </FormattedString.Spans>
                                </FormattedString>
                            </Label.FormattedText>
                        </Label>
                    </Grid>

                    <!-- Workout list -->
                    <CollectionView Grid.Row="2"
                                    Margin="15,0,15,80"
                                    ItemsSource="{Binding SelectedDiary.GroupedWorkouts}">
                        <CollectionView.EmptyView>
                            <Label FontSize="30"
                                   HorizontalTextAlignment="Center"
                                   Text="No logs" />
                        </CollectionView.EmptyView>
                        <CollectionView.ItemTemplate>
                            <DataTemplate>
                                <Frame x:DataType="models:GroupedWorkoutsModel">
                                    <Grid RowDefinitions="auto,auto,2,auto">
                                        <Label Grid.Row="0"
                                               FontSize="20"
                                               Text="{Binding Key}"
                                               TextColor="{DynamicResource TextColourPrimary}" />
                                        <Label Grid.Row="1"
                                               Margin="0,0,00,10"
                                               Text="Back, Chest"
                                               TextColor="{DynamicResource TextColourSecondary}" />

                                        <BoxView Grid.Row="2"
                                                 BackgroundColor="{DynamicResource BackgroundColourPrimary}"
                                                 CornerRadius="1"
                                                 HeightRequest="2" />

                                        <CollectionView Grid.Row="3" ItemsSource="{Binding Items}">
                                            <CollectionView.ItemTemplate>
                                                <DataTemplate x:DataType="databaseModels:LogTbl">
                                                    <Grid ColumnDefinitions="*,*">
                                                        <Label Grid.Column="0" HorizontalTextAlignment="End">
                                                            <Label.FormattedText>
                                                                <FormattedString>
                                                                    <FormattedString.Spans>
                                                                        <Span Text="{Binding Weight}" TextColor="{DynamicResource TextColourPrimary}" />
                                                                        <Span Text=" kg" TextColor="{DynamicResource TextColourPrimary}" />
                                                                    </FormattedString.Spans>
                                                                </FormattedString>
                                                            </Label.FormattedText>
                                                        </Label>
                                                        <Label Grid.Column="1" HorizontalTextAlignment="End">
                                                            <Label.FormattedText>
                                                                <FormattedString>
                                                                    <FormattedString.Spans>
                                                                        <Span Text="{Binding Reps}" TextColor="{DynamicResource TextColourPrimary}" />
                                                                        <Span Text=" reps" TextColor="{DynamicResource TextColourPrimary}" />
                                                                    </FormattedString.Spans>
                                                                </FormattedString>
                                                            </Label.FormattedText>
                                                        </Label>
                                                    </Grid>
                                                </DataTemplate>
                                            </CollectionView.ItemTemplate>
                                        </CollectionView>
                                    </Grid>
                                </Frame>
                            </DataTemplate>
                        </CollectionView.ItemTemplate>
                    </CollectionView>
                </Grid>
            </ScrollView>

            <Border Grid.Row="0"
                    Margin="20"
                    Padding="0"
                    HeightRequest="50"
                    HorizontalOptions="Center"
                    Stroke="Transparent"
                    StrokeThickness="5"
                    VerticalOptions="End">
                <Border.StrokeShape>
                    <RoundRectangle CornerRadius="30" />
                </Border.StrokeShape>
                <Border.Background>
                    <LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
                        <GradientStop Offset="0.0" Color="#0ED473" />
                        <GradientStop Offset="1.0" Color="#17CC54" />
                    </LinearGradientBrush>
                </Border.Background>
                <Border.Shadow>
                    <Shadow Brush="#0ED473"
                            Opacity="0.5"
                            Radius="70"
                            Offset="0,0" />
                </Border.Shadow>
                <HorizontalStackLayout>

                    <Label Grid.Column="1"
                           Margin="10"
                           FontFamily="LASolid"
                           FontSize="30"
                           HeightRequest="30"
                           HorizontalTextAlignment="Center"
                           Text="&#xf04b;"
                           TextColor="White"
                           WidthRequest="50" />
                    <Label Grid.Column="1"
                           Margin="10"
                           FontFamily="LASolid"
                           FontSize="30"
                           HeightRequest="30"
                           HorizontalTextAlignment="Center"
                           Text="&#xf067;"
                           TextColor="White"
                           WidthRequest="50">
                        <Label.GestureRecognizers>
                            <TapGestureRecognizer Tapped="AddExcersie_Tapped" />
                        </Label.GestureRecognizers>
                    </Label>
                </HorizontalStackLayout>
            </Border>
            <Grid Grid.Row="1"
                  BackgroundColor="{DynamicResource BackgroundColourSecondary}"
                  ColumnDefinitions="*,*"
                  HeightRequest="75">
                <Grid.Shadow>
                    <Shadow Brush="#cdd2e6"
                            Opacity="1"
                            Radius="100"
                            Offset="0,0" />
                </Grid.Shadow>
                <Label Grid.Column="0"
                       FontFamily="LASolid"
                       FontSize="30"
                       HorizontalTextAlignment="Center"
                       Text="&#xf46d;"
                       TextColor="{DynamicResource TextColourPrimary}"
                       VerticalTextAlignment="Center" />
                <Label Grid.Column="1"
                       FontFamily="LASolid"
                       FontSize="30"
                       HorizontalTextAlignment="Center"
                       Text="&#xf1fe;"
                       TextColor="{DynamicResource TextColourPrimary}"
                       VerticalTextAlignment="Center" />
            </Grid>
        </Grid>
    </pages:BasePageTemplate.Content>
</pages:BasePageTemplate>

IeuanWalker avatar Nov 12 '22 12:11 IeuanWalker

@IeuanWalker yes it looks like you have a CollectionView inside a ScrollView, such that it will expand to infinite height and create all rows up front.

Can you rework this to get rid of the ScrollView? CollectionView can scroll, and you could make use of the header & footer if your layout is more complicated?

jonathanpeppers avatar Nov 16 '22 19:11 jonathanpeppers

@jonathanpeppers ahh ok

Did try using the CollectionView.Header, but when i did nothing rendered.

Will try again over the weekend

IeuanWalker avatar Nov 16 '22 20:11 IeuanWalker

@jonathanpeppers nothing rendering was caused by this - https://github.com/dotnet/maui/issues/8934

Even after changing the layout to use collectionView.Header the perforamnce is exactly the same. This is the updated layout -

<pages:BasePageTemplate x:Class="FitNote.Pages.HomePage"
                        xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
                        xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                        xmlns:databaseModels="clr-namespace:FitNote.Database.Models"
                        xmlns:mct="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
                        xmlns:models="clr-namespace:FitNote.Models"
                        xmlns:pages="clr-namespace:FitNote.Pages"
                        xmlns:vm="clr-namespace:FitNote.ViewModels"
                        x:DataType="vm:HomeViewModel">
    <pages:BasePageTemplate.Resources>
        <ResourceDictionary>
            <mct:IsNotNullConverter x:Key="IsNotNullConverter" />
            <mct:IsEqualConverter x:Key="IsEqualConverter" />
        </ResourceDictionary>
    </pages:BasePageTemplate.Resources>
    <pages:BasePageTemplate.Content>
        <Grid RowDefinitions="*,auto">

            <!-- Workout list -->
            <CollectionView Grid.Row="0" ItemsSource="{Binding SelectedDiary.GroupedWorkouts}">
                <CollectionView.Header>
                    <Grid RowDefinitions="230,65">
                        <!-- Dates -->
                        <Border Grid.Row="0"
                                Margin="-2"
                                Padding="0"
                                BackgroundColor="{DynamicResource BackgroundColourSecondary}"
                                HeightRequest="230"
                                Stroke="{DynamicResource BackgroundColourSecondary}"
                                StrokeThickness="0">
                            <Border.StrokeShape>
                                <RoundRectangle CornerRadius="0,0,20,20" />
                            </Border.StrokeShape>
                            <VerticalStackLayout Padding="0,30,0,0" Spacing="0">
                                <Label Margin="0,0,20,0"
                                       FontFamily="LASolid"
                                       FontSize="30"
                                       HorizontalOptions="End"
                                       Text="&#xf013;"
                                       TextColor="{DynamicResource TextColourPrimary}">
                                    <Label.GestureRecognizers>
                                        <TapGestureRecognizer Tapped="OnSettings_Tapped" />
                                    </Label.GestureRecognizers>
                                </Label>

                                <Label Margin="25,5,0,15"
                                       FontAttributes="Bold"
                                       FontSize="20"
                                       Text="{Binding SelectedDiary.Date, StringFormat='{0:MMMM yyyy}'}"
                                       TextColor="{DynamicResource TextColourPrimary}" />
                                <CollectionView FlowDirection="RightToLeft"
                                                ItemSizingStrategy="MeasureFirstItem"
                                                ItemsLayout="HorizontalList"
                                                ItemsSource="{Binding Dates}"
                                                SelectedItem="{Binding SelectedDiary}"
                                                SelectionMode="Single">
                                    <CollectionView.ItemTemplate>
                                        <DataTemplate>
                                            <Grid Padding="10"
                                                  x:DataType="models:DiaryHomePageModel"
                                                  BackgroundColor="Transparent"
                                                  RowDefinitions="70, 30">
                                                <Border Grid.Row="0"
                                                        Padding="0"
                                                        BackgroundColor="{DynamicResource BlueLightColour}"
                                                        HeightRequest="70"
                                                        Stroke="Transparent"
                                                        StrokeThickness="5">
                                                    <Border.StrokeShape>
                                                        <RoundRectangle CornerRadius="200" />
                                                    </Border.StrokeShape>
                                                    <Border.Triggers>
                                                        <DataTrigger Binding="{Binding IsSelected}"
                                                                     TargetType="Border"
                                                                     Value="true">
                                                            <Setter Property="BackgroundColor" Value="{DynamicResource PurpleLightColour}" />
                                                            <Setter Property="Stroke" Value="{DynamicResource PurpleDarkColour}" />
                                                        </DataTrigger>
                                                    </Border.Triggers>
                                                    <VerticalStackLayout Padding="10">
                                                        <Label HorizontalTextAlignment="Center"
                                                               Text="{Binding DayOfTheWeekLetter}"
                                                               TextColor="{DynamicResource BlueDarkColour}" />
                                                        <Label HorizontalTextAlignment="Center"
                                                               Text="{Binding Date, StringFormat='{0:dd}'}"
                                                               TextColor="Black" />
                                                    </VerticalStackLayout>
                                                </Border>
                                                <Ellipse Grid.Row="1"
                                                         Margin="0,10"
                                                         Fill="Transparent"
                                                         HeightRequest="10"
                                                         WidthRequest="10">
                                                    <Ellipse.Triggers>
                                                        <DataTrigger Binding="{Binding IsSelected}"
                                                                     TargetType="Ellipse"
                                                                     Value="true">
                                                            <Setter Property="Fill" Value="#4E16FF" />
                                                        </DataTrigger>
                                                    </Ellipse.Triggers>
                                                </Ellipse>
                                                <VisualStateManager.VisualStateGroups>
                                                    <VisualStateGroupList>
                                                        <VisualStateGroup x:Name="CommonStates">
                                                            <VisualState x:Name="Normal" />
                                                            <VisualState x:Name="Selected">
                                                                <VisualState.Setters>
                                                                    <Setter Property="BackgroundColor" Value="Transparent" />
                                                                </VisualState.Setters>
                                                            </VisualState>
                                                        </VisualStateGroup>
                                                    </VisualStateGroupList>
                                                </VisualStateManager.VisualStateGroups>
                                            </Grid>
                                        </DataTemplate>
                                    </CollectionView.ItemTemplate>
                                </CollectionView>
                            </VerticalStackLayout>
                        </Border>

                        <!-- Workout time and total weight -->
                        <Grid Grid.Row="1"
                              Margin="0,20"
                              ColumnDefinitions="*,3,*"
                              HeightRequest="65">
                            <Label Grid.Column="0"
                                   HorizontalOptions="Center"
                                   VerticalTextAlignment="Center">
                                <Label.FormattedText>
                                    <FormattedString>
                                        <FormattedString.Spans>
                                            <Span FontFamily="LASolid"
                                                  FontSize="20"
                                                  Text="&#xf2f2;"
                                                  TextColor="{DynamicResource TextColourPrimary}" />
                                            <Span FontSize="15"
                                                  Text="12m"
                                                  TextColor="{DynamicResource TextColourPrimary}" />
                                        </FormattedString.Spans>
                                    </FormattedString>
                                </Label.FormattedText>
                            </Label>

                            <BoxView Grid.Column="1"
                                     BackgroundColor="{DynamicResource BackgroundColourSecondary}"
                                     CornerRadius="1.5"
                                     HeightRequest="35"
                                     IsVisible="{Binding SelectedDiary.TotalWeight, Converter={StaticResource IsNotNullConverter}}"
                                     WidthRequest="3" />

                            <Label Grid.Column="2"
                                   HorizontalOptions="Center"
                                   IsVisible="{Binding SelectedDiary.TotalWeight, Converter={StaticResource IsNotNullConverter}}"
                                   VerticalTextAlignment="Center">
                                <Label.FormattedText>
                                    <FormattedString>
                                        <FormattedString.Spans>
                                            <Span FontFamily="LASolid"
                                                  FontSize="20"
                                                  Text="&#xf44b;"
                                                  TextColor="{DynamicResource TextColourPrimary}" />
                                            <Span FontSize="15"
                                                  Text="{Binding SelectedDiary.TotalWeight, StringFormat='{0}Kg'}"
                                                  TextColor="{DynamicResource TextColourPrimary}" />
                                        </FormattedString.Spans>
                                    </FormattedString>
                                </Label.FormattedText>
                            </Label>
                        </Grid>
                    </Grid>
                </CollectionView.Header>
                <CollectionView.EmptyView>
                    <Label FontSize="30"
                           HorizontalTextAlignment="Center"
                           Text="No logs" />
                </CollectionView.EmptyView>


                <CollectionView.ItemTemplate>
                    <DataTemplate>
                        <Border x:DataType="models:GroupedWorkoutsModel" Style="{StaticResource Card}">
                            <Grid RowDefinitions="auto,auto,2,auto">
                                <Label Grid.Row="0"
                                       FontSize="20"
                                       Text="{Binding Key}"
                                       TextColor="{DynamicResource TextColourPrimary}" />
                                <Label Grid.Row="1"
                                       Margin="0,0,00,10"
                                       Text="Back, Chest"
                                       TextColor="{DynamicResource TextColourSecondary}" />

                                <BoxView Grid.Row="2"
                                         BackgroundColor="{DynamicResource BackgroundColourPrimary}"
                                         CornerRadius="1"
                                         HeightRequest="2" />

                                <CollectionView Grid.Row="3" ItemsSource="{Binding Items}">
                                    <CollectionView.ItemTemplate>
                                        <DataTemplate x:DataType="databaseModels:LogTbl">
                                            <Grid ColumnDefinitions="*,*">
                                                <Label Grid.Column="0" HorizontalTextAlignment="End">
                                                    <Label.FormattedText>
                                                        <FormattedString>
                                                            <FormattedString.Spans>
                                                                <Span Text="{Binding Weight}" TextColor="{DynamicResource TextColourPrimary}" />
                                                                <Span Text=" kg" TextColor="{DynamicResource TextColourPrimary}" />
                                                            </FormattedString.Spans>
                                                        </FormattedString>
                                                    </Label.FormattedText>
                                                </Label>
                                                <Label Grid.Column="1" HorizontalTextAlignment="End">
                                                    <Label.FormattedText>
                                                        <FormattedString>
                                                            <FormattedString.Spans>
                                                                <Span Text="{Binding Reps}" TextColor="{DynamicResource TextColourPrimary}" />
                                                                <Span Text=" reps" TextColor="{DynamicResource TextColourPrimary}" />
                                                            </FormattedString.Spans>
                                                        </FormattedString>
                                                    </Label.FormattedText>
                                                </Label>
                                            </Grid>
                                        </DataTemplate>
                                    </CollectionView.ItemTemplate>
                                </CollectionView>
                            </Grid>
                        </Border>
                    </DataTemplate>
                </CollectionView.ItemTemplate>
            </CollectionView>

            <Border Grid.Row="0"
                    Margin="20"
                    Padding="0"
                    HeightRequest="50"
                    HorizontalOptions="Center"
                    Stroke="Transparent"
                    StrokeThickness="5"
                    VerticalOptions="End">
                <Border.StrokeShape>
                    <RoundRectangle CornerRadius="30" />
                </Border.StrokeShape>
                <Border.Background>
                    <LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
                        <GradientStop Offset="0.0" Color="#0ED473" />
                        <GradientStop Offset="1.0" Color="#17CC54" />
                    </LinearGradientBrush>
                </Border.Background>
                <Border.Shadow>
                    <Shadow Brush="#0ED473"
                            Opacity="0.5"
                            Radius="70"
                            Offset="0,0" />
                </Border.Shadow>
                <HorizontalStackLayout>

                    <Label Grid.Column="1"
                           Margin="10"
                           FontFamily="LASolid"
                           FontSize="30"
                           HeightRequest="30"
                           HorizontalTextAlignment="Center"
                           Text="&#xf04b;"
                           TextColor="White"
                           WidthRequest="50" />
                    <Label Grid.Column="1"
                           Margin="10"
                           FontFamily="LASolid"
                           FontSize="30"
                           HeightRequest="30"
                           HorizontalTextAlignment="Center"
                           Text="&#xf067;"
                           TextColor="White"
                           WidthRequest="50">
                        <Label.GestureRecognizers>
                            <TapGestureRecognizer Tapped="AddExcersie_Tapped" />
                        </Label.GestureRecognizers>
                    </Label>
                </HorizontalStackLayout>
            </Border>
            <Grid Grid.Row="1"
                  BackgroundColor="{DynamicResource BackgroundColourSecondary}"
                  ColumnDefinitions="*,*"
                  HeightRequest="75">
                <Grid.Shadow>
                    <Shadow Brush="#cdd2e6"
                            Opacity="1"
                            Radius="100"
                            Offset="0,0" />
                </Grid.Shadow>
                <Label Grid.Column="0"
                       FontFamily="LASolid"
                       FontSize="30"
                       HorizontalTextAlignment="Center"
                       Text="&#xf46d;"
                       TextColor="{DynamicResource TextColourPrimary}"
                       VerticalTextAlignment="Center" />
                <Label Grid.Column="1"
                       FontFamily="LASolid"
                       FontSize="30"
                       HorizontalTextAlignment="Center"
                       Text="&#xf1fe;"
                       TextColor="{DynamicResource TextColourPrimary}"
                       VerticalTextAlignment="Center" />
            </Grid>
        </Grid>
    </pages:BasePageTemplate.Content>
</pages:BasePageTemplate>

IeuanWalker avatar Nov 18 '22 21:11 IeuanWalker

@IeuanWalker If the data in the collection is read-only, try using the OneTime binding and try CompressedLayout.IsHeadless="true" in the layouts.

angelru avatar Dec 05 '22 12:12 angelru

Some optimizations went into this, could you try the latest version, maybe wait for the next .NET 8 preview to come out and try if it's better there?

jfversluis avatar Mar 14 '23 12:03 jfversluis

Hi @IeuanWalker. We have added the "s/try-latest-version" label to this issue, which indicates that we'd like you to try and reproduce this issue on the latest available public version. This can happen because we think that this issue was fixed in a version that has just been released, or the information provided by you indicates that you might be working with an older version.

You can install the latest version by installing the latest Visual Studio (Preview) with the .NET MAUI workload installed. If the issue still persists, please let us know with any additional details and ideally a reproduction project provided through a GitHub repository.

This issue will be closed automatically in 7 days if we do not hear back from you by then - please feel free to re-open it if you come back to this issue after that time.

ghost avatar Mar 14 '23 12:03 ghost

We've added this issue to our backlog, and we will work to address it as time and resources allow. If you have any additional information or questions about this issue, please leave a comment. For additional info about issue management, please read our Triage Process.

ghost avatar Mar 14 '23 12:03 ghost

@IeuanWalker #12130

Same problem, maybe you can improve performance a bit by removing nested CollectionViews, Although BindableLayout also has performance issues/memory leaks, I also noticed that when tapping on an element of a BindableLayout inside a CollectionView (takes a few seconds).

angelru avatar Mar 14 '23 12:03 angelru

@jfversluis @jonathanpeppers @mattleibow

Sorry only just got back to my project, this is still an issue.

I've reorganised the layout, and its not really a loading delay issue now, its a scrolling performance issue. When scrolling its quite laggy.

IeuanWalker avatar Apr 14 '23 17:04 IeuanWalker

Here's the latest repo - https://github.com/IeuanWalker/MauiIssueRepo-7494

Just like before if you remove the inner collectionview/ bindable layout, it performs fine (line 55)

IeuanWalker avatar Apr 14 '23 17:04 IeuanWalker

Duplicate of #12130

jonathanpeppers avatar Apr 14 '23 18:04 jonathanpeppers

I marked duplicate to apply any activity/votes here to the other issue, thanks.

jonathanpeppers avatar Apr 14 '23 18:04 jonathanpeppers