Windowscommunitytoolkit: Reduce the toolkit impact on application size

Created on 24 Feb 2020  路  4Comments  路  Source: windows-toolkit/WindowsCommunityToolkit

Describe the problem this feature would solve

Trying to know what is the impact of the toolkit on the application final size, I've created two blank applications using Visual Studio. On one of them, I've added a dependency to Microsoft.Toolkit.Uwp.UI. I've only added the nuget dependency. I'm not using anything from the library.

Here are the sizes of the applications' dll when compiled in release using .Net Native:

| | x86 | x64 |
| ------ |:------:|:------:|
| Default blank app | 748 | 919 |
| Using Toolkit |6,171 | 7,253 |

Values are in KB. .Net Native directives' files are empty..

This huge impact comes from the fact that the blank app template is super minimal.
On our application, we are seeing a 2MB increase on both x86 and x64. This is still an important impact (knowing that nothing is used).

Is there a way to reduce the impact of the toolkit on the final binary size ?

Sample projects

UwpToolkitBinaryImpact.zip

feature request help wanted in progress

All 4 comments

Thanks for submitting a new feature request! I've automatically added a vote 馃憤 reaction to help get things started. Other community members can vote to help us prioritize this feature in the future!

Removing the Json.NET dependency should help in the future, that's tracked by this item: https://github.com/windows-toolkit/WindowsCommunityToolkit/issues/3060, not sure if that'll line up for the 7.0 release though as there's a blocking bug in the System.Text.Json package, which is still another dependent package until .NET 5.

There may be an opportunity to investigate where we're using this dependency and clean that up or isolate it though.

@vgromfeld can you add some more details here about your recent investigations, especially in regards to the XAML Metadata stuff you looked at recently?

Yes, looking at the symbols available in the final binary, I've found that even without any runtime directive, the binary still contains a lot of symbols related to the community toolkit. My initial guess was that since they are not used, they should have been automatically removed. But, it is not the case.

Looking at the app XamlTypeInfo, I found that a Microsoft_Toolkit_UWP_UI_Controls_Provider instance is added to an _otherProviders list. This class is generated by the XAML compiler in order to build the controls/dependencies. This is the one pulling all the references for all the unused controls. It contains a link to each control available from the community toolkit...

The XAML compiler has a DoNotGenerateOtherProviders control flag to force it to not automatically include the third party XamlTypeInfo files into the application main XamlTypeInfo. I've enabled it in a sample app but didn't see the impact I was expecting.

I first try with a blank app containing only a WrapPanel:

  • The app compiled and worked as expected.
  • It changes the binary size from 5 497Kb (default compiler behavior) to 5 119Kb (_DoNotGenerateOtherProviders_ flag enabled). This saves only 378 Kb.
  • The final binary was still containing symbols of unused controls like BladeItem.

I also tried with a more "complicated" control: InAppNotification.

  • I faced a lot of Windows.UI.Xaml.Markup.XamlParseException in the runtime code when using the _DoNotGenerateOtherProviders_ flag
  • Those exceptions do not contain any useful information about the issue 馃槬.
  • After investigation, it appears that they come from missing entries for StretchChild, CameraPreview and others in the app's XamlTypeInfo.
  • In the end, after adding empty styles to force them to be part of the app XamlTypeInfo, I get a working app.
  • The application binary's size goes from 5 502Kb to 5 299Kb. It decreases only by 203Kb.

I suspect all the static dependency properties to be the remaining roots to the controls symbols. Because they are static fields, they are not removed by _.Net Native_. I t guess that this is why changing the XAML compiler behavior is not helping that much. We can try to replace the dependency properties fields by properties as we've done for some classes but I'm not sure if the XAML runtime will like that...
Reducing the number of controls in each package, can be a good way to limit the impact on the app binary.

Was this page helpful?
0 / 5 - 0 ratings