Over the last week I’ve been exploring different ways to measure the time it takes for an app to launch and be ready for the user to interact with. I’ll go into more detail on this topic in subsequent posts but I wanted first to take a bit of a side track into thinking about the future for cross platform app development using .NET. In this post we’re going to discuss startup performance for apps built using .NET and how this could influence how the cross platform frameworks of today (XamarinForms/Maui and Uno Platform) evolve going forward.
The two cross platform app frameworks we’re going to talk about in this post are Xamarin Forms (and by association .NET Maui) and the Uno Platform. In a lot of ways these frameworks benefit from the same underlying technology, Xamarin iOS, Xamarin Android and UWP. This will evolve into .NET for iOS, .NET for Android and WinUI in the future but the points we’ll discuss in this post will still be applicable.
It’s worth observing that Xamarin Forms and Uno differ in that Xamarin Forms uses its own platform independent abstraction whereas Uno provides implementations for iOS, Android, etc based on a UWP app. This means that Uno doesn’t need to provide a platform implementation for UWP.
When it comes to iOS and Android both Xamarin Forms and Uno suffer from similar problems when it comes to defining the user experience, which results in a significant performance hit, particularly on Android. Both frameworks rely on the underlying platform components, subsequently suffering from the performance bottleneck of having to interop with the native platform.
When looking at startup performance I noted that both Xamarin Forms and Uno were significantly slower to start than an equivalent Flutter app. My testing was done on Android, since this is where most developers end up having to tune their application for performance. Given that none of the apps were doing anything on startup, other than rendering a very basic layout, it can only be assumed that the .NET based frameworks either needed to load more on application startup, or that there were some performance issues related to rendering the user experience. Note here that I did try an empty Xamarin Android application and it performed similar to a Flutter app on startup, suggesting that the performance hit with Xamarin Forms and Uno was mainly user interface related.
Let’s assume that the startup performance hit on Android for Xamarin Forms and Uno is entirely related to rendering the user experience, and more specifically related to the interop between the .NET based application and the underlying native platform. If this is the case, then should we be looking for a long term solution that eliminates, or at least significantly reduce, the interop cost? And more significantly, how does Flutter avoid having to pay this tax?
Answering this second question may provide a solution for the first. Flutter avoids paying the interop cost by simply avoiding using any of the native platform controls. Instead it treats the screen as a canvas on which it renders the layout for the app. With this in mind, we should be looking for ways to replicate this for .NET based applications.
What’s interesting is that both Xamarin Forms team (well, now the .NET Maui team) and the Uno team have already made a start in this direction. The .NET Maui team have invested in options for the rendering of controls using Skia and the Uno Platform already has a backend that uses Skia. The Uno Skia implementation was initially created to support WPF and Linux platforms but in theory there is no reason this couldn’t be used on any platform that supports Skia.
It would seem that migrating to using Skia for rendering would be the logical choice. However, there’s more to switching to Skia than simply rendering elements to the screen. For example, if the frameworks no longer use the underlying native controls, accessibility, and specifically tools like screen readers, become an issue. A lot more work (already done by Google as part of implementing Flutter) needs to be invested in order to make sure all the standard metaphors of the target platform are implemented.
Whilst Skia may be the long term future for .NET based cross platform applications, we’re a long way from that right now. The next milestones for both Xamarin Forms (.NET Maui) and Uno Platform will be to support WinUI/Project Reunion and of course .NET 6. This will be a convergence point for both frameworks as they roll out new versions that will support .NET 6 and Windows.