6

I have a collection view that shows chat messages, it has 10 possible data templates. Each data template contains a flexlayout(because I need to horizontally align it at left or right, like chat bubbles) and inside these flexlayouts, we have a single grid which may show an image, a label, a map or a media player. It loads very fast but is very slow while scrolling. I tried to take off the flexlayout but grid doesn't obey the LayoutOptions End/Start that I need, then I swapped FlexLayout by a ContentView that fills the screen(horizontally) and I was abble to align horizontally its childs. I have noticed no performance improvements with this change, maybe even got worse. Also I have read and done changes following suggestions from Optimizing App Performance but seems not be enough.

Below I have my collectionview tag and an example of one data template, the others are very similar, almost doesn't have difference. My doubt is how can I improve this scenario?

CollectionView

<CollectionView x:Name="ChatCollectionView" SelectionMode="None" HorizontalScrollBarVisibility="Never" VerticalScrollBarVisibility="Always" ItemsUpdatingScrollMode="KeepLastItemInView" ItemTemplate="{StaticResource MsgTemplateSelector}" Margin="5,0,5,0" />

One of data templates

<DataTemplate x:Key="DefaultMsg">
    <FlexLayout Direction="Row" MinimumWidthRequest="50" JustifyContent="{Binding MsgAlign}">
            <Grid Padding="0" Margin="0,10,0,0">
                <Grid.RowDefinitions>
                    <RowDefinition />
                    <RowDefinition Height="20"></RowDefinition>
                </Grid.RowDefinitions>

                <BoxView Grid.Column="0" Grid.ColumnSpan="1" Grid.Row="0" Grid.RowSpan="2" CornerRadius="5" BackgroundColor="{Binding MsgBg}" />
                <Label Grid.Row="0" Grid.Column="0" Text="{Binding msg}" TextColor="Black" />

                <Grid Grid.Row="1" Grid.Column="0">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="*" />
                        <ColumnDefinition Width="20" />
                    </Grid.ColumnDefinitions>

                    <Label Grid.Column="0" Grid.Row="0" TextColor="DarkGray" FontSize="12">
                        <Label.FormattedText>
                            <FormattedString>
                                <Span Text="&#xf017; ">
                                    <Span.FontFamily>
                                        <OnPlatform x:TypeArguments="x:String" Android="Font-Awesome-Free-Solid.otf#FontAwesome5Free-Solid" iOS="FontAwesome5Free-Solid" />
                                    </Span.FontFamily>
                                </Span>
                                <Span Text="{Binding date}" />
                                <Span Text=" at " />
                                <Span Text="{Binding hour}" />
                            </FormattedString>
                        </Label.FormattedText>
                    </Label>

                    <ActivityIndicator Grid.Column="1" Grid.Row="0" Color="#ff9000" HeightRequest="15" WidthRequest="15" IsRunning="{Binding sending}" IsVisible="{Binding sending}" HorizontalOptions="End" />
                    <Label Grid.Column="1" Grid.Row="0" Text="{Binding icon}" IsVisible="{Binding sent}" TextColor="{Binding IconColor}" FontSize="15" HorizontalOptions="End">
                        <Label.FontFamily>
                            <OnPlatform x:TypeArguments="x:String" Android="Font-Awesome-Free-Solid.otf#FontAwesome5Free-Solid" iOS="FontAwesome5Free-Solid" />
                        </Label.FontFamily>
                    </Label>
                </Grid>
            </Grid>
    </FlexLayout>
</DataTemplate>
Éder Rocha
  • 1,538
  • 11
  • 29
  • 1
    Would avoid using FlexLayout here at all cost, why bother using templates then if you what flex to create a dynamic template on the fly. Create templates for different cases and use stacklayout. – Nick Kovalsky May 30 '20 at 16:04
  • I agree with you that would be the best choise, can you give me an example? All examples that I have seen with stacklayout, has a single template defined inside the collectionview tag. – Éder Rocha May 30 '20 at 17:40
  • @Nick Kovalsky a little doubt here, if collection view already put elements as a list(stacked), why do I need a stacklayout? – Éder Rocha May 30 '20 at 17:51
  • 1
    Are you using the latest Xamarin.forms? I found some issues in Github and it looks like Xamarin team is working on this problem. Here is the issues: [CollectionView scrolling is jittery](https://github.com/xamarin/Xamarin.Forms/issues/7152) and [CollectionView jittering on Android with GridItemsLayout](https://github.com/xamarin/Xamarin.Forms/issues/8718) – nevermore Jun 01 '20 at 06:07
  • @JackHua-MSFT thank you for commenting this. I've been reading these links you shared here but people still having same problem even after updates. – Éder Rocha Jun 01 '20 at 16:58
  • Yes, I mean the team has noticed this problem and is working on it. It may be improved in the future. – nevermore Jun 02 '20 at 05:45
  • 1
    I've found supposed solutions [here](https://codetraveler.io/2020/07/12/improving-collectionview-scrolling/) and [here](https://github.com/xamarin/Xamarin.Forms/issues/7152#issuecomment-830120231) but neither actually worked for me :\ I've also found [these alternative controls](https://github.com/xamarin/Xamarin.Forms/issues/8640#issuecomment-839884028) which can be used to replace CollectionView in _some_ cases... – BlueRaja - Danny Pflughoeft Jun 17 '21 at 05:23
  • @ÉderRocha did you find solution for this? – Cassini Apr 03 '23 at 21:10
  • 1
    @Cassini I did some upgrades of Xamarin package and it is more stable now. The changes of code that I did had no significant results. – Éder Rocha Jul 04 '23 at 18:41

3 Answers3

2

In my case the problem was in the span, I removed and put a normal label. My scroll is fluid again.

1

I would recommend using Compiled Bindings. These 2 websites beautifully explain what Compiled Binding is and how to use it.

Alireza Sattari
  • 181
  • 2
  • 12
-1

Reduce the size of your images to 10-20kb. It is likely your problems stem from massively over-sized images. This article was a major help for us:

https://www.redbitdev.com/post/optimizing-images-for-mobile-devices

We saw all collectionview scrolling lag issues disappear by managing our image sizes. We attempted to utilize a DataTemplateSelector as recommended in this article:

https://codetraveler.io/2020/07/12/improving-collectionview-scrolling/

However, it did not resolve our issues even when fully implemented. Additionally, the code in the article and the correlated repository does not use XAML and is difficult to integrate if your views are XAML heavy. Please forgive any ignorance or brevity.

Dharman
  • 30,962
  • 25
  • 85
  • 135
BigMarty
  • 135
  • 1
  • 6
  • In our case removing 100% all images didn't improve scroll performance at all... Xamarin is very bad. Compare it to the facebook app written in react native, it works butter smooth – user1034912 May 08 '21 at 05:28