Improving Navigation Speed and Performance #22793
Replies: 41 comments 14 replies
-
maybe you can offer a video to compare they, i don't understand what you're saying. i use collectionview alway use Task.Run to load some data, when navigation to this page, collectionview will show a Activityindicator, load more data also have a Activityindicator |
Beta Was this translation helpful? Give feedback.
-
I agree with @LewisEKay because I noticed the same. It only happens once, the very first time. The next times you open this page it loads almost immediately. I always thought that its a .NET thing. @xtuzy Its not about loading data. Its about loading/building the UI the first time. In my case for example the data is already there. But if you navigate to the page it has to create the UI for this data and this is what is really laggy. Even in release mode with AOT the screen hangs about 1-2 seconds. |
Beta Was this translation helpful? Give feedback.
-
@jonathanpeppers have anything to offer here? |
Beta Was this translation helpful? Give feedback.
-
I experience the exact same thing. Navigation in appshell when you go to a page for the first time is extremely slow. +- 2-3 seconds between tapping the tab item and the page showing up. This occurs as soon as a layout is somewhat complex and has nothing to do with data loading. Subsequent page loads are instantly, probably because the entire page is kept in memory. Enabling AOT and LLVM somewhat helps, but the entire app still feels very laggy compared to xamarin forms |
Beta Was this translation helpful? Give feedback.
-
@LewisEKay Could you create examples showing the types of issues you describe? I agree that performance, in general, could be improved, but coming up with actionable items and goals could turn this from a proposal to actionable issues we (as a community) could then tackle and have a baseline for showing progress. |
Beta Was this translation helpful? Give feedback.
-
This is inherited from Xamarin Forms. In Shell when navigating to a page that has a "complex" layout, that crash occurs, slow navigation. It is enough to create a page with 7 entry with its styles, bindings and navigate to this page. If the animation is deactivated, this blocking or slow navigation does not occur. |
Beta Was this translation helpful? Give feedback.
-
https://youtube.com/shorts/x5xYREfKQhA Please see this video for an example of what's happening. As you can see from the video, the SettingsView loads fine, but the MonkeysView is slow. Now I understand this is most likely happening due to it needing to account for bindings and load the data within its startup. But is there a way we can speed this up so it's almost instant on first tap? This is the code for the MonkeysView. <ScrollView>
<VerticalStackLayout
Spacing="25"
Padding="30,0"
VerticalOptions="Center">
<Image
Source="dotnet_bot.png"
SemanticProperties.Description="Cute dot net bot waving hi to you!"
HeightRequest="200"
HorizontalOptions="Center" />
<Label
Text="Hey this is the monkeys page!"
SemanticProperties.HeadingLevel="Level1"
FontSize="32"
HorizontalOptions="Center" />
<CollectionView ItemsSource="{Binding Monkeys}">
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Label Text="{Binding Name}"/>
<Label Grid.Column="1" Text="{Binding Age}"/>
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</VerticalStackLayout>
</ScrollView> This is the code for MonkeysView.xaml.cs public partial class MonkeysView : ContentPage
{
public ObservableCollection<MonkeyModel> Monkeys { get; set; } = new ObservableCollection<MonkeyModel>();
private Random _random;
private List<string> _names = new List<string>
{
"Mong Clumbort",
"Margaret",
"King Kong",
"Monkeh",
"Jimmy",
"Hairy Jeff",
"Ragged Pete",
"Timothy Grumpleton",
"Barry Hedgemane",
"Mo",
"Jim Bob",
"Trey"
};
public MonkeysView()
{
InitializeComponent();
BindingContext = this;
_random = new Random();
for(int i = 0; i < 30; i++)
{
Monkeys.Add(new MonkeyModel
{
Age = _random.Next(1,30),
Name = _names[_random.Next(0,_names.Count)]
});
}
}
}
public class MonkeyModel
{
public string Name { get; set; }
public int Age { get; set; }
} |
Beta Was this translation helpful? Give feedback.
-
This is my app, i feel my page that have CollectionView is fast, i do all in code sharex-20230417211003.mp4 |
Beta Was this translation helpful? Give feedback.
-
@xtuzy do you use code behind instead of XAML as well as Task.Delay(500)? |
Beta Was this translation helpful? Give feedback.
-
code like this:
notice, i use PureWeen.Maui.FixesAndWorkarounds, i don't know if it is related |
Beta Was this translation helpful? Give feedback.
-
Has anyone profiled their app to maybe give some insight into what the biggest offenders are? Or if you can share a sample project that shows the behavior, we can profile on our side, thanks! |
Beta Was this translation helpful? Give feedback.
-
@jonathanpeppers I'm more than willing to share our code of a problematic app we have, but I can't do it publicely. Would you be interested in gaining access to the github repo? |
Beta Was this translation helpful? Give feedback.
-
Sure, you can contact me at the email address on my GitHub profile if you need to. Thanks. |
Beta Was this translation helpful? Give feedback.
-
@LewisEKay you use collectionview in verticalstacklayout and scrollview, maybe this is reason, you can try delete verticalstacklayout and scrollview, move image and label to header of collectionview |
Beta Was this translation helpful? Give feedback.
-
@jonathanpeppers I have sent you a mail and have given you access to the repo |
Beta Was this translation helpful? Give feedback.
This comment has been minimized.
This comment has been minimized.
-
@xaviersand, I messed up with the |
Beta Was this translation helpful? Give feedback.
-
Hi everyone! I also encountered a problem with shell tabs. I'm actually a newbie in MAUI, so it could be my fault, but anyway. The essence of the problem is when content of tabs is quite overloaded, first (after app launch) navigation between tabs is incorrect. Watch the video please. 24-04-18-16-20-09.mp4After application started, I'm trying to open Tab №6 (or 4/5/6/7, it doesn't matter). Desired tab even opens for a while, but then the last Tab opens. It "works" with all tabs except the first three (they work well). Firstly the tab contained a lot of labels. After that I've googled that it's bad idea to use so much labels, so I decided to use only one label which contains FormattedText to imitate lot of labels. But it did not help. P.S. of course I launch the program in release mode Demo: https://github.com/dima059/MauiShellTabs
@KevinJalais, can you tell me how to check if I using the "debug mode" while deploying? |
Beta Was this translation helpful? Give feedback.
-
when can we expect a smooth user experience? Navigating to pages featuring CollectionView or BindingLayout is notably sluggish, with more complex pages suffering from even greater delays, to the point where it feels slower than web-based interfaces. |
Beta Was this translation helpful? Give feedback.
-
The same design and UI, on other platforms such as React native, Flutter and Android are both native and very smooth, but they lag on the Maui and cannot be used in the product at all. This performance is too poor and completely beyond imagination. Please fix it as soon as possible |
Beta Was this translation helpful? Give feedback.
-
I'm going to convert this issue to a discussion. If users have specific repros they can log issues with that will help us narrow down your particular brand of performance woes. There are a number of android fixes coming to CV in SR6 that I'm hoping will help folks in some scenarios. |
Beta Was this translation helpful? Give feedback.
-
This problem is very easy to reproduce, just use a collectionview, fill in some data, or nest a few widgets, such as carouselview, bindinglayout, etc., and navigate to the current page to see the latency and stuttering beyond imagination. We made an APP with maui, and the user experience feedback was very poor, but we were helpless, there was no solution, so we had to wait for Microsoft to fix it. With such an easy reproducibility problem, why hasn't Microsoft solved it in two years? Can't we recruit more people? How long are we going to wait? |
Beta Was this translation helpful? Give feedback.
-
From my experience opening an issue with a repro project doesn't help. I had an issue closed because of that before. I opened an issue with a reproducable project and it was the same problem as before: It just sits there without any attention. Like this issue. Like other issues. I don't know what the problem is. Wrong focus on minor problems? Too much work for too less people? Microsoft makes so much money, cant they just hire more? Anyway the navigation is still poor and I agree with @xyeie that it's quite easy to reproduce and notice. But I actually gave up doing the extra work with creating issues with repros because of the (missing) feedback I got from these. So if this is not going to be fixed I'm fine with that. I wouldn't choose MAUI for my next project. Comparing to all the other fancy and amazing fast mobile app engines, MAUI is convenient to develop with but the user feedback is a disaster and we stuck on addressing them. |
Beta Was this translation helpful? Give feedback.
-
Unfortunately, that is still an issue. Navigating to a page, even one with a small number of components, can be really lagging, even without data loading. Has anyone found a way to improve this?
|
Beta Was this translation helpful? Give feedback.
-
In fact, many people experience and know this problem, but it is ignored or not solved. So I started learning flutter and stopped using all components of DotNet. |
Beta Was this translation helpful? Give feedback.
-
I use the following pattern for responding to user interactions that are likely to take time: async void OnButtonClicked(object sender, EventArgs args)
{
Button btn = (Button) sender;
btn.IsEnabled = false;
await Task.Delay(50);
await Shell.Current.GoToAsync("//animals/monkeys");
btn.IsEnabled = true;
} The justification is to inform the user that the event has been received asap. The await Task.Delay, no matter how small, is enough to give the user instant notification (via disabling the button) of something is happening before it is happening. The 50ms is quick, so, some users tend to not feel delayed by it, and, in fact, they will get a hint from visual cue. It also has the additional benefit of guarding against the user mashing the button. |
Beta Was this translation helpful? Give feedback.
-
Nalu.Maui.Navigation also has a built-in 60ms delay (which can eventually be disabled) in order to let the touch animation (or button disable) appear on the screen. To have a fast navigation, we usually have a lightweight page which shows titles and loaders (i.e. activity indicators / shimmerview) and when the data is ready we display the actual content. Also, lifecycle methods in |
Beta Was this translation helpful? Give feedback.
-
I also found that navigation can get sluggish when a page has a complex ViewModel and UI. From my personal experience, the following steps help me improve the situation:
For example:
|
Beta Was this translation helpful? Give feedback.
-
An underlying theme I see is minimizing or eliminating code from the constructor and/or the event that triggered the navigation. Making event handlers async and adding await Task.Delay() appears as an effective mitigation of the problem because it moves the heavy lifting away from the events triggering the navigation. Another thing that has been seen is that ObservableCollection can be quite chatting in their change notifications which can have a real impact on the UI thread especially during bulk load stages of the ObservableCollection. This is why some solutions involve workarounds on ObservableCollection (e.g. 1. use List for zero notification, 2. use a custom ObservableRangeCollection implementation, 3. populate the list in a non-UI thread, 4. Use components with a DelayLoad or LoadOnDemand feature, 5 use a third-party CollectionView component) These things can all fall in the family of adopting positive coding patterns. Perhaps these concepts can be collated into a best practices blog or WIKI. |
Beta Was this translation helpful? Give feedback.
-
I created an app MauiLoadTest to flesh out the best practices when dealing with a CollectionView that needs to be populated with 12345 items. Whilst you will need a Telerik license to open, build and run the app the Wiki and the source file BestPage.xaml.cs may be enough to further aspects of this discussion. |
Beta Was this translation helpful? Give feedback.
-
Description
Using both Xamarin Forms and Maui for many years now I’ve noticed that page navigation performance is not great when the view needs to load quite a few items, this could even just be a CollectionView, with bindings, with a few items in that can cause the issue. It also occurs when navigating between shell tabs.
The issue primarily being where the page will begin navigating, maybe jitter as it’s coming into view then lock up the UI thread and finally pop in with content.
I’ve seen some posts stating that a good way to solve it is by adding a Task.Delay(500) to OnAppearing so that the view can animate in before attempting content load, but adding this in doesn’t make it function like an android app that’s made in Android Studio. You still get a delay before any content is shown.
if you look at other apps not made with Maui, when navigating it will be smooth and load almost instantly, such as spotify being able to select a tab and within less than half a second you have data populated straight from a server too.
Public API Changes
Not sure entirely how this can be implemented in code better but maybe some better documentation detailing how to get around these navigation performance issues.
Intended Use-Case
In my apps it’s very important for a quick experience of loading pages, as it is with most apps.
Beta Was this translation helpful? Give feedback.
All reactions