dotnet / dotnet/maui

Improve linking of Microsoft.Maui.Controls.* assemblies

Open
#8,593 3 comments 3 reactions 3 assignees Assigned to @simonrozsival View on GitHub
area-architecture legacy-area-perf perf/general proposal/open t/enhancement ☀️
Dominant language
C#
Stars
23.3k
Forks
2k
Avg merge
1d 10h
Merged PRs (30d)
297

Description

### Description

#### Control -> Handler Mapping

https://github.com/dotnet/maui/blob/1ba45f950315e7eb3a805948ec4bb980278b6b06/src/Controls/src/Xaml/Hosting/AppHostBuilderExtensions.cs#L49-L59

We have this massive list of direct references to XAML controls to handlers.

We could use something like this: https://github.com/dotnet/maui/issues/7258

#### Linking

Initially from https://github.com/dotnet/maui/pull/5028#issuecomment-1059565674

The issue is that Xaml is a form of code that the trimmer can't see. It can reference Types, and since the trimmer can't see which Types it uses, the trimmer doesn't know it needs to keep those Types.

I can think of the following options to resolve this:

1. Don't mark Microsoft.Maui.Controls as "Trimmable".
- We can still take some of the other changes here to resolve trimmer warnings, and possibly trim `Microsoft.Maui.dll`. This would be at least a step in the right direction.

2. Take this change as is. And if someone is using LoadFromXaml in their app, instruct them to add `` to their .csproj. This will instruct the trimmer to preserve the entire assembly. That way people who don't use LoadFromXaml can save the size off their apps. And people who do use it can make it work.

3. We could add a `[DynamicDependency]` on the LoadFromXaml API. This way, if this method is used in the app, the Types can be preserved. However, there are the following drawbacks with this approach:
1. We would really want to say that _all_ types in the Microsoft.Maui.Controls assembly be preserved. That way we wouldn't have to list each Type that could be used in Xaml. However, the trimmer doesn't have this feature (yet). We would have to ask for it to be implemented to say `[DynamicDependency(DynammicallyAccessedMemberTypes.All, "*", "Microsoft.Maui.Controls")]`.
2. This would only address the issue for our built-in controls. It wouldn't solve the problem for 3rd party extenders who wanted to allow their control assemblies to be trimmed.

4. We could add a [Feature Switch](https://github.com/dotnet/designs/blob/main/accepted/2020/feature-switch.md) to the `LoadFromXaml` behavior. Let's call it `Microsoft.Maui.LoadFromXaml.IsSupported`. When `LoadFromXaml.IsSupported=false`, calling LoadFromXaml will throw an exception instructing the developer to set `LoadFromXaml.IsSupported=true`. By default in a trimmed, Release built version of an app, `LoadFromXaml.IsSupported` will be `false`. For all other times, it will be `true`. The benefit that this approach has is when `LoadFromXaml.IsSupported=true` we can use an [ILLink.Descriptor.xml](https://github.com/dotnet/linker/blob/main/docs/data-formats.md#descriptor-format) file that will tell the trimmer "when LoadFromXaml.IsSupported=true, then preserve this whole assembly".
1. 3rd party extenders could also follow this approach. That way their control assemblies can be marked as "Trimmable", but when LoadFromXaml is enabled, their whole assembly can be preserved as well.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.