Skip to content

Investigate limitations and document findings of enabling NativeAOT for MAUI iOS application #80907

@ivanpovazan

Description

@ivanpovazan

Description

Investigate potential issues and limitations of NativeAOT with .NET MAUI iOS applications:

  1. .NET MAUI template app
  2. .NET MAUI Podcast app

Goals

  • Document discovered findings and limitations
  • Based on the results propose the follow-up work
  • Measure performance of NativeAOT targeting iOS platforms, and compare results against MonoAOT, the measurements should include: the application size: disk size (SOD) and bundle size (.ipa), build and startup time

Preview 6

Our main focus for the initial releases is the application size.
Apps were built and measured using: https://github.com/xamarin/xamarin-macios/tree/release/8.0.1xx-preview6 release

.NET MAUI template app

Building a .NET MAUI iOS sample application dotnet new maui gives the following results:

.NET MAUI ios app Mono-p6 NAOT-p6 diff (%)
SOD (Mb) 40,24 50,13 25%
.ipa (Mb) 14,68 16,59 13%

Mono-p6 in the table represents results obtained with Mono .NET8 preview6, while NAOT-p6 represents results obtained with NativeAOT .NET8 preview6

Identified issues that contribute to the size regression with NativeAOT are:

Estimated savings

  • Estimated savings in app sizes by applying optimizations for NativeAOT from Step1 to Step4

    .NET MAUI ios app Mono-p6 NAOT-p6 Step1 Step2 Step3 Step4
    SOD (Mb) 40,24 50,13 41,93 40,5 27,58 TBD
    .ipa (Mb) 14,68 16,59 13,43 12,85 10,23 TBD

    NOTE: Results for StepN mean that all the previous steps Step1..N have been implemented

  • Estimated difference (%) in app sizes compared to Mono-p6 by applying optimizations for NativeAOT from Step1 to Step4

    .NET MAUI ios app Mono-p6 NAOT-p6 Step1 Step2 Step3 Step4
    diff SOD (%) NaN 24,56% 4,20% 0,64% -31,46% TBD
    diff .ipa (%) NaN 13,00% -8,53% -12,48% -30,32% TBD

    NOTE: Diffs in the table mean that if for example we implement Step1 and Step2, the .ipa size with NativeAOT will be 12,48% smaller compared to Mono

.NET MAUI Podcast app

Estimated savings

  • Preliminary data (only estimated for Step3 improvements with NativeAOT):

    .NET MAUI ios app Mono-p6 Step3 diff (%)
    SOD (Mb) 62,67 43,59 -30,45%
    .ipa (Mb) 24,37 17,43 -28,47%

Preview 7

Apps were built and measured using: https://github.com/xamarin/xamarin-macios/tree/release/8.0.1xx-preview7 release. The results show that NativeAOT generates ~30% smaller applications compared to Mono (as it has been estimated above).

.NET MAUI template app

MAUI ios app Mono-p7 NAOT-p7 diff (%)
SOD (Mb) 40,52 27,41 -32,37%
.ipa (Mb) 14,82 10,14 -31,56%

.NET MAUI Podcast app

MAUI podcast app Mono-p7 NAOT-p7 diff (%)
SOD (Mb) 62,81 42,18 -32,84%
.ipa (Mb) 24,46 16,85 -31,10%

Other findings

  • Fix Infinite recursion when generated code wrongly dispatches explicit interface calls
  • Objective-C interop and GC API support:
  • Support static registrar with NativeAOT:
  • Dynamic registrar with NativeAOT - [NOT A PROBLEM]
    • We did not detect any need to support dynamic registrar with NativeAOT so far - especially because NativeAOT does not seem to be required for inner-dev loop experience. Nevertheless, bellow are listed findings when dynamic registrar is enabled for NativeAOT:
      • When building the application with dynamic registrar, the application crashes when ObjC runtime tries to register UIKit.UIGestureRecognizer+Callback`1 type while it is fetching its interface map against Foundation.INSObjectProtocol:
      default 12:06:26.833235+0200    HelloMauiiOS    *** Terminating app due to uncaught exception 'System.ArgumentException', reason: 'Interface not found. (System.ArgumentException)
      at Internal.Reflection.Execution.ExecutionEnvironmentImplementation.VerifyInterfaceIsImplemented(RuntimeTypeHandle, RuntimeTypeHandle) + 0x78
      at System.Reflection.Runtime.TypeInfos.RuntimeTypeInfo.GetInterfaceMap(Type) + 0xa8
      at Registrar.SharedDynamic.PrepareInterfaceMethodMapping(Type) + 0x114
      at Registrar.Registrar.RegisterTypeUnsafe(Type, List`1&) + 0x1fbc
      at Registrar.Registrar.RegisterType(Type, List`1&) + 0x44
      at Registrar.DynamicRegistrar.Register(Type) + 0x18
      at ObjCRuntime.Class.GetClassHandle(Type, Boolean, Boolean&) + 0x168
      at Foundation.NSObject.AllocIfNeeded() + 0x40
      at UIKit.UIPanGestureRecognizer..ctor(Action`1) + 0x40
      at Microsoft.Maui.Controls.Platform.Compatibility.ShellFlyoutRenderer.Microsoft.Maui.Controls.Platform.Compatibility.IShellFlyoutRenderer.AttachFlyout(IShellContext context, UIViewController content) + 0xf8
      

Metadata

Metadata

Assignees

Type

No type

Projects

Status

No status

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions