A Solution to the known problem of Xamarin Forms's Android startup time.
My solution after 2 weeks of work, for StartUp time on Android Without AOT is Dual SplashScreen.
Actually, there is no magic here. The same init time is remains. This solution
is based on UX "Perceived Performance". UX here will be much better.
Instead of the user sees a long-time delay on one splash screen (or without splashscreen, which is worse),
Now, the user sees 2 splash screens:
- The normal splash screen, and…
- Screenshot of the first interactive screen the user engaging when the app starts. I called it 'FirstScreen', which I implement it with MainActivity. The user sees what screen he going to get while progress bar is showing, and when the rendering is finished, the image (as a background) is switched with the real Page.
If we analyze the delay at the start (cold start), there are 2 kinds of delay:
- Init code of different components (Forms.init, DI init (e.g. autofac etc.))
- Rendering of the page.
So, by splitting the init code to the first activity (SplashActivity) and leaving only the Render delay to FirstScreen (or MainActivity) we can split the delay time by 2 pages, and that way the user sees half of the total delay, on each screen.
Users starts to count the seconds on static screen. So, if you move fast to another screen, you good. The perception now is the app starts FASTER (even actually, as you'll see later the app starts even slower a little bit).
I put on Github my solution DualSplash. Check it out.
Credits to Ideas and components:
Acr.UserDialogs of Allan Ritchie AllanRitchie.
XF Page_Load event by Mohamed Yousuf yousufctec.
Splash screen in XF by Adam Pedley AdamP.
Thank you All!
- This Repo contains 1 XF Core project and 2 android projects.
SingleSplash – the problem – here you'll see normal splash screen with long delay (10sec on nexus4)
DualSplash – the solution – here you'll see the splash end in about 6sec (on nexus4) and moved to next page (which at start is a screenshot of the actual final interactive XF page) with progress bar Acr.UserDialogs of @AllanRitchie(https://forums.xamarin.com/profile/AllanRitchie)
If you start the 2 apps, you can think app 2 -DualSplash is faster, but in fact it is slower (on slow devices like nexus4) by 1sec (!) because the added activity, but the init methods are the same.
Few Notes here:
In order to see the Progress bar when page is loading , OnCreate need to finish fast to put the native control (by Acr.UserDialogs or the normal Native one) and afterwards let XF Loadapplication(…) do the Xaml loading. To do so I used splash layer-list (https://xamarinhelp.com/creating-splash-screen-xamarin-forms/ - better approach)
and async code in OnCreate.
You need to screenshot the FirstScreen for different device sizes (and not like I did, take one image and resize it to all device sizes), because Xaml is rendered differently on different screen sizes.
Another approach would be not to screenshot but to put an image of Template of empty page with the same design of your App and progress bar inside.
FirstScreen is shown with the screenshot as background at start until XF loads the Xaml Page. When finished rendering, there is the need to change the background back to normal, and it have to happened right after finished loading. For that I used the Trick of @yousufctec(https://forums.xamarin.com/profile/yousufctec) , XF Page Load Event
I spread over all the code Stopwatch measurements to see the performance on every step of the app. You can see the output on logcat or debug output. You can see that DualSplash takes even longer actually, but the UX perception is that it's much Faster.
The code is flexible. You can move some init code from SplashActivity to MainActivity if you see the delay takes longer on the splash screen and move it to FirstScreen. It all depends on your App and device. Play with it!
I believe the Code can be tweaked further, you are welcome to improve it.