Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Some optimization tips on android when using a shadow in the data template of collview/listview? #16

Closed
themronion opened this issue Aug 1, 2020 · 11 comments

Comments

@themronion
Copy link
Contributor

Hey, it's me again. I am wondering wether it is possible to somehow optimize the appearance of datatemplates in a collectionview/listview with shadows? I guess i am getting some lags because the shadows are getting rendered in bitmaps and then disposed all over again when i am scrolling my list (as i understand how your code works). I will attach a gif of what i have now. Maybe it is possible to somehow save the created shadows in cache (maybe using FFImageLoading plugin, don't know) - so that when we have a lot of shadow items in a list we can reduce the lag? Or at least u can advice me something to minimize the lag (because on older phones i have serious lagging). Appreciate your answer and once again - love your work!
ezgif com-video-to-gif

@roubachof
Copy link
Owner

Hey man !
First we need to be sure it's the bitmap shadows that are lagging.
Normally since RecyclerView implements cell reuse, only N shadow bitmaps should be rendered at the same time (where N is the number of visible cells). Since it is reused, it shouldn't be disposed either.
Also, if you using CollectionView be aware that is has some serious lagging issues caused by the GC: https://www.sharpnado.com/gittrends-lags/
If you share your repro sample I can have a look and see if they are indeed disposed.

@themronion
Copy link
Contributor Author

themronion commented Aug 1, 2020

Yep, when i tried without the shadows the lagging decreased a lot. Happens both with listview and collectionview. I can share my layout for the data template, would be grateful if u take a look. You can substitute the bindings with random text and substitute the images. Try to add at least 10 items to the list with shadows and without them.

            <CollectionView.ItemTemplate>
                    <DataTemplate>
                        <sh:Shadows CornerRadius="10"  Padding="{Binding FramePadding}" Shades="{sh:SingleShade Offset='0, 6',
                                    Opacity=0.1, BlurRadius=25,
                                    Color=Black}">
                            <Frame CornerRadius="10" HasShadow="False">
                                <StackLayout Spacing="0">
                                    <StackLayout Orientation="Horizontal" Spacing="14">
                                        <Image HeightRequest="12" HorizontalOptions="Start" Source="ic_note.png"/>
                                        <Label  FontSize="14" Text="{Binding ClosedDateTimeShort}" HorizontalTextAlignment="Start" HorizontalOptions="StartAndExpand" VerticalOptions="Center"/>
                                        <Image Source="ic_forwardgray.png" HorizontalOptions="End"/>
                                    </StackLayout>
                                    <Grid RowDefinitions="Auto,Auto,Auto" ColumnDefinitions="Auto,*,Auto">
                                        <Label Text="Here i have a bindable layout" Grid.Row="0" Grid.ColumnSpan="3"/>
                                        <BoxView Grid.Row="1"  Grid.ColumnSpan="3"  HeightRequest="1" Color="#E0E0E0"/>
                                        <Frame HasShadow="False" Grid.Row="2" Grid.Column="0" Padding="7,3,7,3" CornerRadius="10" BackgroundColor="{Binding BackgroundColor}" HorizontalOptions="Start">
                                            <Label FontSize="14" TextColor="{Binding TextColor}" Text="{Binding StatusName}"/>
                                        </Frame>
                                        <Image Grid.Row="2" Grid.Column="1" Source="{Binding CardImage}" WidthRequest="24" HorizontalOptions="End"/>
                                        <Label VerticalOptions="Center" Grid.Row="2"  Grid.Column="2" Text="{Binding FormattedCost}" TextColor="Black" FontSize="16"/>
                                    </Grid>
                                    <Grid ColumnDefinitions="Auto,*,Auto" RowSpacing="0" ColumnSpacing="8" IsVisible="{Binding HasCarInfo}">
                                        <Image Grid.Column="0" Source="ic_smallcar.png"/>
                                        <Label Grid.Column="1" Text="{Binding CarInfo.ColorAndModel}" FontSize="14"/>
                                        <Frame HasShadow="False" Grid.Column="2" Padding="7,3,7,3" CornerRadius="10" VerticalOptions="Center" HorizontalOptions="End" BackgroundColor="#F2F2F2">
                                            <Label FontSize="14" Text="{Binding CarInfo.CarStateNumber}"/>
                                        </Frame>
                                    </Grid>
                                </StackLayout>
                            </Frame>
                        </sh:Shadows>
                    </DataTemplate>
                </CollectionView.ItemTemplate>

@roubachof
Copy link
Owner

roubachof commented Aug 1, 2020

layout won't help please provide a repro sample.

@themronion
Copy link
Contributor Author

themronion commented Aug 1, 2020

I can't, unfortunately. Just make an empty page and a collectionview with this data template. Should be close to what i have

@roubachof
Copy link
Owner

I'm afraid I don't have time for this. I just have time for testing a repro sample...

@roubachof
Copy link
Owner

roubachof commented Aug 1, 2020

Waow, I just received 30 minutes of free time. I will right away test Shadows with CollectionView on Android

@roubachof
Copy link
Owner

So I just made a test with a new XF project.
A simple CollectionView, with this xaml:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:App1"
             xmlns:shades="clr-namespace:Sharpnado.Shades;assembly=Sharpnado.Shadows"
             x:Class="App1.MainPage">
    <ContentPage.BindingContext>
        <local:MainPageViewModel />
    </ContentPage.BindingContext>
    <CollectionView ItemsSource="{Binding Pipos}">
        <CollectionView.ItemTemplate>
            <DataTemplate>
                <shades:Shadows CornerRadius="15" Shades="{shades:SingleShade Color=Coral, Offset='0,10', Opacity=0.2, BlurRadius=6}">
                    <Frame Padding="10" Margin="15,5,15,10" CornerRadius="15" HasShadow="False">
                        <StackLayout x:DataType="local:PipoViewModel">
                            <Label HeightRequest="30" Text="{Binding Title}" />
                            <Label HeightRequest="20" Text="{Binding Subtitle}" />
                            <Label HeightRequest="20" Text="{Binding Subsubtitle}" />
                        </StackLayout>
                    </Frame>
                </shades:Shadows>
            </DataTemplate>
        </CollectionView.ItemTemplate>
    </CollectionView>

</ContentPage>

To be sure I'm only testing Shadows performance.
I also enabled logging to monitor dispose.
I generated 100 hundred items.

  1. Shadows as expected are never disposed and reused
  2. The scrolling is super smooth

ezgif com-optimize

Well it's a bad gif but I achieve nearly 60 fps.
So I'm afraid Shadows is not the bad boy here sorry...

Are you using GlideX for Images ? If you're not images are not cached and could cause serious performance issues

@themronion
Copy link
Contributor Author

themronion commented Aug 1, 2020

Hm, maybe really its my layout that is too complex... I tried with and without the images - no effect. I will send u a full empty project on monday with my layout, maybe the problem will arise there, thx!

@themronion
Copy link
Contributor Author

Also, maybe this happens because in my template the height of items may be different?

@roubachof
Copy link
Owner

roubachof commented Aug 2, 2020

So I took a look at your cell layout and it is way too complex.
First you have:

<SL>
  <SL>
  <Grid>
  <Grid>

Where you can just use a single grid for all of these.

Second, you use the attribute 'Auto' for sizing your column and row definition.
DON'T DO THAT IN CELLS.
Cause every time you will update your bindings (every cell reuse) it will re-layout your cell, this is awful.
Use fixed size, never 'Auto' in list cells.

Third, you should have fixed height for your cell, cause it will force the relayout of the cell, this is also awful :)
Then you can set the ItemSizingStrategy=ItemSizingStrategy.MeasureFirstItem. It will be so much performant.
I will advise you to test this first, it may be the simplest thing to change in your case and also the most impactful.

Finally, you don't use caching for your images, I suggest GlideX.

Also, the CollectionView and probably the ListView have GC issues, this is an issue currently under investigation: xamarin/Xamarin.Forms#11483. Till then you can increase your nursery size, it is a HORRIBLE workaround, but still effective.

I'm closing the issue now cause it's not related with Shadows, just apply the good layout practices above and it should be ok.

@themronion
Copy link
Contributor Author

Thank you for the tips!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants