Laden...

Maui: Bilder in CollectionView Performance unter Android

Letzter Beitrag vor 6 Monaten 8 Posts 564 Views
Maui: Bilder in CollectionView Performance unter Android

Hallo zusammen,

ich versuche aktuell eine Anwendung, die ich mal mit Angular und Ionic entwickelt habe, mit Maui neu zu programmieren. Es geht dabei um eiune Verwaltung von Hörbüchern. Ziel ist, dass ich die gleiche Anwendung (Codebasis) sowohl unter Android als auch unter Windows verwenden kann.

Eine Ansicht davon ist eine Liste mit allen Covern der registrierten Hörbüchern. Die Cover werden in einem CollectionView angezeigt. Unter Windows ist das kein Problem. Aber unter Android ist es unmöglich in der Liste zu scrollen.
Die Cover sind dabei als Bild-Datein auf dem jeweiligen Gerät vorhanden. Im Image verwende ich einen FileImageSource mit Bindung auf den jeweiligen Pfad zur Bilddatei.

Hier der Xaml-Code

<CollectionView ItemsSource="{Binding Audiobooks}">
    <CollectionView.ItemTemplate>
        <DataTemplate x:DataType="models:Audiobook">
            <VerticalStackLayout Padding="15">
                <Image WidthRequest="150" HeightRequest="150">
                    <Image.Source>
                        <FileImageSource File="{Binding ImagePath}" />
                    </Image.Source>
                </Image>
            </VerticalStackLayout>
        </DataTemplate>
    </CollectionView.ItemTemplate>
    <CollectionView.ItemsLayout>
        <GridItemsLayout Orientation="Vertical" Span="{Binding Columns}" />
    </CollectionView.ItemsLayout>
</CollectionView>

Wie gesagt: Unter Windows keine Probleme. Es handelt sich hier um ca. 300 Bilder alle in der Größe 150x150 Pixel.
Unter Android bewegt sich der Scrollview 10 10 Sekunden vielleicht um einen Pixel. Also absolut nicht bedienbar.

Im Logcat hab ich immer Meldungen in dieser Art:

[Choreographer] Skipped 218 frames!  The application may be doing too much work on its main thread.
[EGL_emulation] app_time_stats: avg=1919.20ms min=165.86ms max=3672.54ms count=2
[OpenGLRenderer] Davey! duration=3854ms; Flags=0, FrameTimelineVsyncId=126296, IntendedVsync=1178942486484, Vsync=1179109153144, InputEventId=0, HandleInputStart=1179117296448, AnimationStart=1179117309748, PerformTraversalsStart=1179117329048, DrawStart=1182617312148, FrameDeadline=1179125819810, FrameInterval=1179116961548, FrameStartTime=16666666, SyncQueued=1182636644548, SyncStart=1182642993148, IssueDrawCommandsStart=1182768628148, SwapBuffers=1182770803848, FrameCompleted=1182803662348, DequeueBufferDuration=13300, QueueBufferDuration=254500, GpuCompleted=1182803662348, SwapBuffersCompleted=1182771395948, DisplayPresentTime=0, CommandSubmissionCompleted=1182770803848, 
[OpenGLRenderer] Davey! duration=3807ms; Flags=0, FrameTimelineVsyncId=126311, IntendedVsync=1179125819810, Vsync=1182759152998, InputEventId=0, HandleInputStart=1182769331548, AnimationStart=1182769392948, PerformTraversalsStart=1182769805048, DrawStart=1182770136148, FrameDeadline=1182825819662, FrameInterval=1182768873148, FrameStartTime=16666666, SyncQueued=1182770324948, SyncStart=1182779469248, IssueDrawCommandsStart=1182926049948, SwapBuffers=1182927572448, FrameCompleted=1182942847248, DequeueBufferDuration=16100, QueueBufferDuration=185900, GpuCompleted=1182942847248, SwapBuffersCompleted=1182927938848, DisplayPresentTime=0, CommandSubmissionCompleted=1182927572448, 
[audiobooks.maui] Explicit concurrent copying GC freed 3501(160KB) AllocSpace objects, 0(0B) LOS objects, 49% free, 10MB/20MB, paused 236us,36us total 14.939ms

Für mich sieht es so aus, als ob das Rendern im MainThread so extrem viel Performance braucht und daher die UI blockiert. Gibt es eine Möglichkeit, das Rendern irgendwie in einen Thread zu verschieben? Bzw. gibt es eine andere, performantere Anzeige-Möglichkeit unter Android?

Ich bin für jeden Tipp dankbar 😉

Kannst du mal ausprobieren, wie die Performance bei weniger Bildern ist (z.B. 50, 100, 200), also ob es generell auftritt oder ob es kontinuierlich schlechter wird, je mehr Bilder angezeigt werden?

Meine Erfahrung ist auch, daß Android bei vielen Daten deutlich langsamer ist als Windows.

Und sind die Bilder denn im Original viel größer als 150x150, d.h. werden diese zur Anzeige stark skaliert?

Edit:

In [.NET 8 & .NET 7] Poor performance in scrolling in the image list. werden ähnliche Performance-Probleme beschrieben (ich habe aber nicht alle Beiträge gelesen).

@Th69: Danke für die Antwort...

Guter Ansatz, dass ich das mal mit weniger Bildern probieren 😃. Ja... Bis 50 Bilder läuft es noch flüssig. Ab 60 wird es ein bisschen hakelig und ab 80 ist es nicht mehr bedienbar.

Die Bilder liegen direkt als 150x150 JPG vor. Werden also nicht mehr codeseitig skaliert. Das hab ich schonals ersten Ansatz vorgearbeitet, weil ich dachte, dass die Skalierungsarbeit evtl. Probleme machen könnte. Hat aber nichts geändert.

Was auf dem Desktop gilt, gilt bei Mobile Apps umso mehr: es gehört nur so viel in eine Liste/Grid, wie es ein Anwender auch verarbeiten kann.
Alles andere reduziert die Performance sehr.

@Abt: Ja, das ist klar. Aber wie setzt man das im Fall einer CollectionView um? VirtualScrollView gibt es bei Maui scheinbar nicht oder ich hab da zumindest noch nichts gefunden.

Ich hab jetzt testweise übrigens das Projekt aus dem oben genannten Ticket genommen und ausprobiert. Das läuft zwar nicht flüssig, aber man kann es immerhin bedienen, was bei meinem Projekt schon nicht mehr geht. Also minimal angepasst und statt der Beispielbilder hab ich die Bilder aus meinen Quellen genommen und man kann es immer noch bedienen.

Jetzt hab ich den Verdacht, dass es irgendwie mit dem Binding zusammenhängt. Aber das ist nur ein Verdacht. Ich werde jetzt auf jeden Fall mal das Fremdprojekt step für step so erweitern, dass es meinem Projekt entspricht. Irgendwo muss der Knackpunkt ja sein, der das ganze unbedienbar macht

Das ist ja schon mal gut, daß du die Ursache finden konntest.

Ich habe Maui.VirtualListView gefunden (weiß aber nicht, ob das auch mit Bildern so gut funktioniert).

Das mit der Collection Performance ist ja nix neues (Technologie-übergreifend).
Gibt dazu auch in MAUI nen issue ⇒ Slow Scrolling Performance in CollectionView or ScrollView #17326

Da werden auch verschiedene Lösungsmöglichkeiten diskutiert.

Nativ sollte das mit einem RecyclerView gar keine Probleme bereiten. Es kann tausend Datensätze problemlos anzeigen.

Hierzu habe ich folgenden Link gefunden:
https://github.com/dotnet/maui/issues/21554

Zitate:

(...) CollectionView seems to be really struggling on Android, especially when you scroll through the items quickly. #21554 (...)

(...) Potential solution: GO NATIVE
After digging for hours through recorded scopes and trying to optimize the layout of item templates I found out that the only solution was to write the layout natively. I translated the real-world-complex from XAML to android XML. I setup the RecyclerView to use my layout and bind my collection of items through the adapter. (...)

Vielleicht hilft diese Information