dotnet / dotnet/winforms

Size of WinForms with PublishAot

Open
#9,911 48 comments 15 reactions 1 assignee Claimed by @JeremyKuhne View on GitHub
area-ILLinker/AOT area-Trimming
Dominant language
C#
Stars
4.9k
Forks
1.1k
Avg merge
20h 23m
Merged PRs (30d)
103

Description

I had a look at the size of WinForms app with PublishAot. I think there's a potential to make the size of AOT-compiled self-contained WinForms apps very attractive (single-digit MB range, fully self-contained).

If I add `true` and `<_SuppressWinFormsTrimError>true` to a WinForms default template and `dotnet publish` it I get a 54 MB executable. One might say “still better than Electron” and call it good, but it can actually be _much_ better.

Drilling into the size with [Sizoscope](https://github.com/MichalStrehovsky/sizoscope) one can immediately see something that should not be there: PresentationFramework.

![image](https://github.com/dotnet/winforms/assets/13110571/238f9959-fb1e-4e6b-91c7-26d1a3073055)

Half of WPF gets dragged in because WinForms started using a WPF interface: `ICommand`. And `ICommand` has a [bunch of custom attributes](https://github.com/dotnet/runtime/blob/d34ed289d34b2f9588e10673800d269d7b1a6376/src/libraries/System.ObjectModel/src/System/Windows/Input/ICommand.cs#L14C10-L15) on it that drag in WPF.

We can avoid dragging in WPF if we can make sure the string within the custom attribute doesn't actually resolve. One can hack around it by putting this in the csproj for example:

```xml





```

We cannot ship this hack. The only way I can currently think of to fix this would be to divorce WPF and WinForms and stop putting them into the same NuGet/SDK.

With this out of the way, the size of the executable drops to 25.5 MB. We can do better. One thing that Sizoscope will point out is networking stack. It gets brought in from two places – PictureBox and XML. We already have feature switches in place for both [PictureBox]( https://github.com/dotnet/winforms/pull/6684) and [XML]( https://github.com/dotnet/runtime/pull/84169).
Add this to the csproj to disable these:

```xml

false





```

With this, the size drops to 21.7 MB.

Looking at what's left in Sizoscope, designers stand out. There's many types that come out of DesignerAttribute and EditorAttribute. Can we make a feature switch to strip them? I experimentally stripped them out and the size drops to 15.2 MB. (Tracked in https://github.com/dotnet/runtime/issues/92043)

A thing that Sizoscope currently doesn't show is manifest resources. Out of the 15.2 MB above, 7.5 MB are embedded resources. They currently cannot be trimmed automatically. Clicking through the manifest resources in WinForms assemblies that are part of the application based on Sizoscope, I see that most (all?) are designer related. Can we get rid of them? If so, the size would drop to ~7 MB.

I think there would be potential to shrink this further (e.g. the `TypeConverter` on `TableLayoutSetting+StyleConverter` brings in the entire XML stack with `DtdParser` and everything), but 7 MB for a fully self-contained WinForms app is already quite encouraging.

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.