-
Notifications
You must be signed in to change notification settings - Fork 1.7k
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
Fix DatePicker slow first render (#24929) #24948
base: main
Are you sure you want to change the base?
Conversation
/azp run |
Azure Pipelines successfully started running 3 pipeline(s). |
6f7a817
to
9c97a62
Compare
Okay, I think I went a bit too far. Now just the matter of where should I do this? Unless static constructor of DatePicker.cs is fine. Screen_Recording_20240927-030030.mp4 |
/azp run |
Azure Pipelines successfully started running 3 pipeline(s). |
Failing tests probably require a retry. By the way, some DatePicker.cctorDatePickerExtension.SetText()Full Only heavy thing left is the |
Is this only on Android ? Or better if you do this on iOS do you see performance wins to? |
Sadly currently I don't have any Apple devices to test iOS, but if DatePicker for iOS also uses In general I think initializing like this should improve any case where |
|
Also what do you guys think about maybe making another PR targeting .NET 9.0 which would remove the Also I guess some information about a change breaking this workaround would be needed then. |
The issue got closed with a partial fix as i remember. Fix was done for the iOS part, but not for android. #20547 is still open for droid. |
oh alright I didn't see that sorry. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure the changes help anything at all here?
-
Android puts processor cores to sleep for battery saving purposes. Calling
Task.Run()
on startup when in this state will cause a significant delay as the OS has to "wake up" an extra core. This is probably less noticeable on fast/flagship Pixel devices. I wouldn't recommend starting any threads at startup, until your app needs to make a network request, where you can't avoid it. -
dotnet/runtime has already implemented something like this in .NET 7+:
The first call to DateTime.Now
requires the BCL to load a "timezone database", in order to do the appropriate math for the current time. I would not recommend ever using DateTime.Now
, unless you absolutely have to show the current time on the screen to a user. I would only use DateTime.UtcNow
or the equivalent DateTimeOffset
APIs.
So that leaves me with two questions:
- What is the code that is slow? Do we have a
.speedscope
? - Is something in .NET MAUI calling
DateTime.Now
? Can we remove the call instead?
From the linked issue, it feels like we could instead:
^ This could happen when the underlying text box is focused for the first time.
|
Yes, there are 2 speedscopes in linked issue, and 1 somewhere above after the changes.
Also there are precise locations in linked issue. |
|
I've tried
But there are still new things appearing, in this case it's this function maui/src/Core/src/Platform/Android/DatePickerExtensions.cs Lines 48 to 54 in cc683f0
maui-app_20240928_194237.speedscope.json I could keep trying to get rid of calls which require time zones but still the @jonathanpeppers isn't there by any chance an event that is fired when app is loaded? Maybe it could be used to initialize everything once, solve all possible issues with DateTime across whole app and not affect startup? |
Looking at this maui/src/Core/src/Platform/Android/DatePickerExtensions.cs Lines 48 to 54 in cc683f0
I'm wondering why is it exactly using
Using Removing it completely makes the date range actually correct with what's passed through |
4162543
to
f6e5853
Compare
After those changes
I think the delay is smaller. Screen_Recording_20240928-234929.mp4After removing the |
Regarding |
Context
I'd say that this solution doesn't look nice but at the same time I don't have other ideas and since it works I'm creating this PR to show my solution.
By the way, I'm completely new to contributing so I'm sorry if something is wrong :)
Description of Change
Based on information from #24929 I've done:
DateTime.Now
andDateTime.ToString()
initialization on startup currently in static constructor, later it probably should be moved somewhere more appropriate.DateTime.Now
andDateTime.ToString()
initialization on worker thread in case someone usesDatePicker
on app's main page.DatePickerDialog
onDatePicker
constructor since it's also slowing down first render (seedotnet trace
available in linked issue), instead it's created only on demand.Issues Fixed
Fixes #24929
This issue also includes
TimePicker
but I haven't looked into it yet.Performance change
Recorded in release configuration on physical android device - Samsung Galaxy A50.
Screen_Recording_20240926-193904.mp4
Screen_Recording_20240926-193355.mp4