Closed PureWeen closed 7 months ago
this problem also exists in net 7
Just tested iOS, wow, much slow.
I'm having a similar problem with GridItemsLayout and described what I've tried/found in: https://github.com/dotnet/maui/issues/17326 -- Does anyone know if the issues are related??
@PureWeen I have noticed that CreateContent() of datatemplate is much slower than in XF, may be here is the problem. because the same template in XF takes 30 ms to create and 200 ms in MAUI. I supposed that MAUI should be much performant than XF but it is not
I observed CollectionView sluggishness in MAUI .NET 7, and even more with .NET 8 iOS compared to Xamarin forms. Multiple issues with grids not resizing properly. Star columns and rows do not behave as expected. I moved a big Xamarin iOS project to MAUI .NET 7, I will not publish it. Will keep updating Xamarin.Forms version. With Android it is even worse. Resizing issues worse than with iOS, CollectionView scrolling slower and jerkier. My Android Xamarin.Forms apps run faster than iOS counterparts. MAU Android apps significantly slower than MAUI iOS. Waiting for .NET 8 was a big disappointment. It brought further performance degradation instead of improvement. I like MAUI coding, but MAUI GUI performance is not acceptable.
any plan for it?
It's worth noting that if anyone is looking at the speed of scrolling in CollectionView or ListView while debugging their app through Visual Studio, it is definitely going to be slower than on an actual release build. The reason for this is there's a lot more visual tree interaction happening with the live visual tree tooling which slows things down significantly.
Having said that, it does seem like it might be slower than it could be on Android even in a release build. I'm working on collecting some traces so we can look at the details a bit more and see where time is being spent.
Here's a speedscope trace from this app running on a Pixel 4 in release mode... dotnet-dsrouter.exe_20231205_163422.speedscope.json
Here's a video of the app running: https://github.com/dotnet/maui/assets/271950/f97cfdf8-631b-4a26-8386-1cc4f40c33bf
I think this is running reasonably fast looking at the video, and nothing stands out too much from the speedscope trace.
@jonathanpeppers thoughts?
@Redth as i said before, CreateContent() method of DataTemplate is much slower in MAUI than in XF on same templates both in debug mode. in XF it takes 20 -30ms to construct template, in MAUI takes 200 ms. Maybe this is the case
The CreateContent()
method is showing a small % in the .speedscope
file above:
When looking for low-hanging fruit while scrolling, I tended to look for things in the 2% range. But there still could be something done here that would help.
I added this section, as this seems to be coming up a lot:
One thing I do see, I think we could completely eliminate this call:
Where it only calls into C# from Java if the TextView.Text
is a "formatted string". So plain strings could avoid the interop.
@Redth, is it worth comparing scrolling in CollectionView or ListView in release mode to scrolling of CollectoinView or ListView in Xamarin.Forms in any mode? I moved a 5 years old Xamarin.Forms project to MAUI .NET 7. Xamarin.Forms ListView and CollectionView scrolling on a physical device (Samsung Galaxy S20) is smooth and fast even when run in Visual Studio debugger with Hot Reload enabled. The MAUI app scrolling is slower, and it is jerky when running on the same device in release mode directly. Pretty much same on iOS, only Android is worse. I think there is more than one cause for poor performance. MAUI Grid.
Somehow in Xamarin.Forms using 'auto' rows and columns did not cause problems I could notice, and Xamarin.Forms Star rows and columns resize as documented. Not in MAUI .NET 7 or .NET8. Star columns and rows behave like 'auto' and that affects controls they are hosting, and controls that are hosting grid cells. ListView and CollectionView in my apps use one-row multiple columns Grid in the DataTemplate. One of the columns is always Star. Other columns width is bound to datasource (List<>). In Xamarin.Forms it works like a charm. In MAUI works too but does not resize properly when device is rotated. The app has 7 pages that have either ListView or CollectionView. In theXamarin.Forms app none of the pages has OnSizeAllocated(). I can rotate the device and everything including CollectionView/ListView resizes correctly. In MAUI the same XAML and code behind produce wrong sizing on load and when device is rotated and not just for CollectionView. In MAUI I had to write OnSizeAllocated() for each page to make it look more or less right, like I did in early Xamarin days. I tried .NET 8 when it was released in November. It is so much worse I went back to .NET 7. The added MAUI code is different between iOS and Android projects. Xamarin.Forms beats MAUI in the 'write code once' area too. If I would not have the Xamarin.Forms app in respective app stores since 2018 and vastly outperforming the MAUI version I might even publish the iOS version. Android still requires some work. But it makes no sense.
is it worth comparing scrolling in CollectionView or ListView in release mode to scrolling of CollectoinView or ListView in Xamarin.Forms in any mode?
That's why we added the section at the top here: https://aka.ms/profile-maui#feature-xyz-was-faster-in-xamarinforms
Compare Release
vs Release
.
Jonathan, in my experience the Release against Release comparison is hugely in favor of Xamarin.Forms. Microsoft MAUI .NET 7 and .NET 8 update notes always refer to improvements (in tests) against previous MAUI versions, The sad thing is I like MAUI coding. I don't like the result, and the ugly tweaks I do to keep layouts intact, more or less, when the screen orientation changes.
@mikebikerider can you share a sample app, .nettrace
, .speedscope
where we can take a look? (and file a new issue)
It sounds like we need to just profile your MAUI app and see what it's doing.
Jonathan, I have to write a sample app. If I do something terribly wrong that should affect both iOS and Android, right? Below is a flyout page with a CollectionView that my code loads from another flyout page.
I issue a call from the previous page: await Shell.Current.GoToAsync("//assets",false); assetsPage.LoadAssets(listedassets, w, Width);
In MAUI iOS the page loads almost immediately. Under Android the calling page freezes for about 30 seconds, before the next page appears. Apparently, under Android await does not wait long enough for the page to load to the point it can start processing GUI code. Everything in MAUI Android seems be slower than in MAUI iOS. So, I do a trick, I call the loading code from a Timer. It kind of works, but first the user sees a mostly blank page: Dispatcher.StartTimer(TimeSpan.FromMilliseconds(500), () => { assetsPage.LoadAssets(listedassets, w, Width); return false; }); I don't need that trick next time I get to the page during the program run, but it is still ugly.
My Xamarin Android apps run faster than their iOS equivalents and code behind is identical except for the platform-specific calls. Not so with MAUI. MAUI iOS GUI updates are faster compared to Android, and I can't use the same common code. So far Xamarin renders do much better job.
Did you profile this app? File an issue with some .nettrace
or .speedscope
files, thanks!
@Redth is right about the release mode. CollectionView scrolling in Android release mode is faster. With Xamarin I could not tell the difference between my app running in the debug mode and release mode. It is different with MAUI. Thank you.
@Redth is right about the release mode. CollectionView scrolling in Android release mode is faster. With Xamarin I could not tell the difference between my app running in the debug mode and release mode. It is different with MAUI. Thank you.
This is because Debug has the Interpreter on (for C# Hot Reload). Details on this here. The Interpreter didn't exist (or was experimental) in the Xamarin days.
We reviewed the app here in our weekly performance meeting, and there is a large performance win we could make in {AppThemeBinding}
.
17% of the time is spent just doing:
Which is inside here for {AppThemeBinding}
:
Traces: collectionview.zip
We can have a look at making this not use an event and rather push the value to the controls. Sort of like how Window works because we only need to propagate if it changes.
After my PR, we got some data from @jonathanpeppers
This generally looks good, my Before:
vs After:
(NOTE just look at the % as the trace duration is not the same)
Traces taken while scrolling a sample on #18505: matthew.zip
This is crazy! Before, it was 45% just inflating (and all the bindings) items:
Inflation is still the top item, but now is only 8.6%!
My PR is building so if anyone has significant issues in their app and wan't to try it out: https://github.com/dotnet/maui/pull/19931
It is a bit of a scary change because it totally flips the order of the theme events, but it may be significant of a fix that makes this worth the scary things. If people try this out and we get some good feedback, then that will also help.
I uploaded a sample MAUI CollectionView app to https://github.com/mikebikerider/CollectionViewSample-net8/tree/master . I wrote the app to explore why MAUI CollectionView pereforms so poorly compared to Xamarin.Forms, especially when a CollectionView resides inside a ScrollView. The sample has two pages. On the first page vertical scroll CollectionView is in a star row of the main grid. The second page vertical scroll CollectionView is inside horizontal scroll ScrollView that is in the star row of the main grid. The stand-alone CollectionView has no issues under either iOS or Android. Second page CollectionView inside the horizontal ScrollView performance, especially on Android, was horrible until I figured out that .net 8 ScrollView incorretly handles the size of hosted controls on iOS and Android. Not just hosted CollectionView. Grids are affected too, a 'star' column is handled as 'auto'. I eventually made it working by correcting the size of the CollectionView (vertical size on Android) or the size of the grid holding the CollectionView and its header (iOS). Tricks that should not be required. ScrollView hosted controls sizing issues under iOS are most noticeable on iPhones with a notch or dynamic island. It seems ScrollView does not take into account safe area insets in both portrait and landscape orientations, and I did not observe that under .net 7. On Android if I don't correct CollectionView vertical size when ItemsSource assigned and OnSizeAllocated() (screen rotated), scrolling more than couple of hundred items is not feasible. After size correction - 20000+. It is an awkward workaround, not a solution.
@mikebikerider the link you posted seems to be private
I changed the repository to public. Thank you for pointing it out.
Description
Given the following layout
the performance on XF is much better than MAUI
Steps to Reproduce
Run the following projects on Android and you'll notice that the scrolling on XF is super smooth compared to MAUI. If you perform really fast scrolling, XF remains smooth whereas MAUI starts to glitch and slow down.
MAUI: MauiCollectionView.zip
XF: XFCOllectionView.zip
I didn't test this on WinUI/iOS yet but it would be good to validate there as well
Link to public reproduction project repository
No response
Version with bug
8.0.0-rc.2.9373
Is this a regression from previous behavior?
Not sure, did not test other versions
Last version that worked well
Unknown/Other
Affected platforms
Android
Affected platform versions
Android
Did you find any workaround?
No response
Relevant log output
No response
Related Issues
https://github.com/dotnet/maui/issues/20433 https://github.com/dotnet/maui/issues/19933 https://github.com/dotnet/maui/issues/20797