Windowscommunitytoolkit: ImageEx causes performance issue on Xbox One S -- Critical

Created on 16 Dec 2019  路  26Comments  路  Source: windows-toolkit/WindowsCommunityToolkit

Describe the bug

I'm designing an app, which home is very likely to NetFlix' home page. Recently I found some performance issue on XBox One S. Please see my repo.
The ImageEx control is used with ItemsRepeater of Microsoft UI.

So it maybe caused by this two controls. When using ImageEx, Xbox One S takes a while to render the UI, and the focus rectangle moves slowly the next vertical item.
I'll tell how to reproduce.

Steps to Reproduce

Steps to reproduce the behavior:
Download my repo, build to XBox One S, and use controller to move focus up ad down.

If use ImageEx, Xbox One S takes a while to render the UI, and the focus rectangle moves slowly the next vertical item.

If use Image, (although this control does not have place holder, I just use it for a comparision), the focus rectangle moves smoothly up and down.

You can watch this video.

If long press up/down stick, XBox One S can't render UI quickly, and this will cause 5+ seconds to render UI.

Expected behavior

A clear and concise description of what you expected to happen.

Screenshots

If applicable, add screenshots to help explain your problem.

Environment

NuGet Package(s): 

Package Version(s): 
Microsoft.Toolkit.Uwp.UI.Controls 6.0.0
Microsoft.UI.Xaml 2.2.190917002(latest 2.3.191211002 stilllllll not work)

Windows 10 Build Number:
- 18363.535

Device form factor:
- [ ] Desktop
- [x] Xbox
- [ ] Surface Hub
- [ ] IoT

Visual Studio 
- [ ] 2017 (version: )
- [x] 2019 (version: 16.4.1) 
- [ ] 2019 Preview (version: )

Additional context

Add any other context about the problem here.

Xbox 馃幃 bug help wanted

All 26 comments

ImageEx causes performance issue on Xbox One S

@hupo376787 Thanks for opening the issue, I was able to reproduce this as well.

@Kyaa-dost to clarify you reproduced the same issue on desktop?

@michael-hawker Correct!

Hi, guys. Thanks for your attention.
I have used apple tv and android tv, the same design likes NetFlix' home page, they all have a very smooth experience, while srolling up/down.
So I hope combining ItemsRepeater and ImageEx, uwp can also reach and surpass them, on every win10 device.

@hupo376787 Just to clarify. Is this issue specific to ImageEx and Xbox ? Do you see the issue if you use Image ? What about on desktop when using ImageEx ? I am trying to understand if the issue is in ItemsRepeater or ImageEx.

Well, I made a table comparing sample app and my production app.

Sample App

Sample app just has an Image and 2 TextBlocks. No converters and other animations.

| | Xbox One S | Desktop(i7 8th, MX250) |
| ------------- | ------------- | ------------- |
| ImageEx | very bad, can't acceptable | somewhat acceptable |
| Image | better than ImageEx, somewhat acceptable | acceptable |

My Production App

My app has much more elements than sample app. I have converters and other animations. See the template below.

| | Xbox One S | Desktop(i7 8th, MX250) |
| ------ | ------ | ------ |
| ImageEx | really can't acceptable, especially long press up/down stick | somewhat acceptable, but some on some low machines, maybe worse |
| Image | can't acceptable, especially long press up/down stick | acceptable |

It seems that even if I use ItemsRepeater and Image, the app still has fluent issue on Xbox One S.

Sample app template:

<DataTemplate x:Key="MovieTemplate"
                      x:DataType="local:Movie">
            <Button Click="Movie_Click"
                    Width="250"
                    DataContext="{x:Bind}"
                    BorderThickness="0"
                    Padding="0"
                    Margin="20 0"
                    CornerRadius="0">
                <StackPanel>
                    <!--<ctl:ImageEx Source="{x:Bind PosterUrl}"
                        PointerEntered="Element_PointerEntered"
                        PointerExited="Element_PointerExited"
                        Height="360"
                        Stretch="UniformToFill"
                        HorizontalAlignment="Stretch"
                        VerticalAlignment="Stretch"
                        PlaceholderSource="/Assets/Clippy.png"
                        PlaceholderStretch="Uniform"
                        ToolTipService.ToolTip="{x:Bind Title}">
                    </ctl:ImageEx>-->
                    <Image Source="{x:Bind PosterUrl}"
                           Height="360"
                        Stretch="UniformToFill"/>
                    <TextBlock Foreground="White" Text="{x:Bind Title}" FontSize="20"/>
                    <TextBlock Foreground="White" Text="{x:Bind Title}" FontSize="24"/>
                </StackPanel>
            </Button>
        </DataTemplate>

My template:

<DataTemplate x:Key="HorizontalTemplate" x:DataType="model:ProductItem">
            <StackPanel
                x:Name="StackPanelCardItem"
                DataContext="{x:Bind}"
                Margin="24,0"
                Tapped="StackPanelCardItem_Tapped">
                <Button
                    Name="ButtonCardItem"
                    Margin="0,0,0,8"
                    Background="Transparent"
                    Windows10version1809:CornerRadius="0"
                    Style="{StaticResource HomeCardButton}"
                    PreviewKeyDown="ButtonCardItem_PreviewKeyDown"
                    PointerEntered="ButtonCardItem_PointerEntered"
                    PointerExited="ButtonCardItem_PointerExited"
                    GotFocus="ButtonCardItem_GotFocus"
                    LostFocus="ButtonCardItem_LostFocus">
                    <Grid
                        x:Name="GridCardItem"
                        Height="{x:Bind is_movie, Converter={StaticResource cardHeightConverter}}"
                        Width="{x:Bind is_movie, Converter={StaticResource cardWidthConverter}}"
                        >
                        <Image Source="{x:Bind cover_image_url, Converter={StaticResource imageUrlCompress}}"/>

                        <!--<controls:ImageEx
                            PlaceholderStretch="Uniform"
                            PlaceholderSource="{Binding is_movie, Converter={StaticResource imageSourceConverter}}"
                            Stretch="Uniform"
                            Source="{x:Bind cover_image_url, Converter={StaticResource imageUrlCompress}}"/>-->

                        <Grid
                            Width="100"
                            HorizontalAlignment="Left"
                            Visibility="{x:Bind helpers:EpisodeStringHelper.EpisodeVisibility(is_movie)}">
                            <Border
                            Background="Gray"
                            Opacity="0.6"
                            Height="30"                                    
                            VerticalAlignment="Bottom"/>
                            <TextBlock
                            Text="{x:Bind helpers:EpisodeStringHelper.EpisodeConverter(number, x:Null), Mode=OneWay}"
                            HorizontalAlignment="Center"
                            VerticalAlignment="Bottom"/>
                        </Grid>
                    </Grid>
                </Button>

                <TextBlock
                    Margin="8,0,0,0"
                    FontSize="16"
                    Text="{x:Bind series_name}"
                    TextTrimming="CharacterEllipsis"/>
                <TextBlock
                    Margin="8,0,0,0"
                    Text="{x:Bind series_category_name}"
                    TextTrimming="CharacterEllipsis"/>
            </StackPanel>
        </DataTemplate>

My app preview:

ezgif-4-00ac5f9cd135

@hermitdave any thoughts on what might be going on here? Thanks.

Not sure @michael-hawker let me think about this. I could try reproduce issue on Xbox though I'm out of town at present.

@hupo376787 Is this still a perf issue or did the workarounds provided in https://github.com/microsoft/microsoft-ui-xaml/issues/1699 resolve this ?

@hupo376787 have you tried simplifying the ImageEx template? Can you try the following

  • use placeholder that is static resource?
  • remove progress ring
  • use ListView rather than Items Repeater (benefit from virtualisation)

Sorry I was confusing Repeater with Items control.

@hermitdave In my sample template, it is really the simplest, just a button contains an Image and 2 textblock. But this is still not good enough on Xbox.

For placeholder, I tried a static resource, seems no improvement.
Any ListView is worse than Itemsrepeater.
Xboxone s has a better gpu, it should not behave like this

@ranjeshj Yes, that helps a little. There still exists perf issue. It seems all control not suitable for Xbox at the first designing.

@hupo376787 issues with large number of ImageEx on ListView is well known. It was raised a long time ago. The solution was to simplify ImageEx template.

Looking at it though Xaml has been simplified and Progress Ring had been removed.
https://github.com/windows-toolkit/WindowsCommunityToolkit/blob/master/Microsoft.Toolkit.Uwp.UI.Controls/ImageEx/ImageEx.xaml

I think only other thing I can think of is doubling of Image in memory - placeholder is hidden not unloaded.

Hmm, when using Image control, not ImageEx, in Itemsrepeater template, the perf seems better, but not good enough, comparing to Android TV devices. I have tried many solutions, vertical ListView + horizontal ListView, vertical Itemsrepeater + horizontal Itemsrepeater, with the simplest template, not good.

Does xboxone limit CPU/gpu under Dev mode? Or something else?

I am not aware of any limitations though what you could do is deploy dotnet native compiled code possibly in release mode - not debug.

@hupo376787 can you confirm that you see this only in debug mode and not when deployed in release?

@hupo376787 can you confirm that you see this only in debug mode and not when deployed in release?

I'm not sure.
Now I swtich to use Image instead of ImageEx, cause ImageEx may casue memory problems.

@hermitdave did you intended for ImageEx to be used in these high-performing scenarios or as just a simple helper for niche scenarios? Want to understand if this is something we should investigate or not or just call out in documentation?

@michael-hawker ImageEx is as it was designed. One solution can't fit all scenarios

@michael-hawker It would be nice to have the prefetcher of images functionality that is within ImageEx and have that as a general image helper for use within normal image control also.

Even although @hermitdave says

One solution can't fit all scenarios

My gut feeling is even within UWP imageEx is a memory hog. I will see if I can put something together to prove my point in the next 2 weeks as I also have an issue in one of my projects that use imageex extensively and after extensive use in app I get "fatal memory errors" where the app just shuts down.

@Pinox this can be fixed by using x:load rather than visibility/opacity. ImageEx was added when UWP was still in 10240 and x:load became available in14393 if I am not mistaken.

thanks @hermitdave , will give it a try. I still need to figure out if I can replicate my issue in a separate project. Not sure if imageex is to blame it can also be a very lazy GC in UWP that is causing my problems.

@Pinox besides that issue which is having two images in memory (placeholder and desired), there is nothing additional done by ImageEx. Good luck finding the bug

@hupo376787 if you're still having issues with the base Image control in an ItemsRepeater please file an issue with your repo steps above on the WinUI repo, thanks!

OK, Thx.

Was this page helpful?
0 / 5 - 0 ratings