Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reduce the toolkit impact on application size #3145

Closed
vgromfeld opened this issue Feb 24, 2020 · 15 comments · Fixed by #3752
Closed

Reduce the toolkit impact on application size #3145

vgromfeld opened this issue Feb 24, 2020 · 15 comments · Fixed by #3752
Labels
feature request 📬 A request for new changes to improve functionality in progress 🚧 In-PR 🚀
Milestone

Comments

@vgromfeld
Copy link
Contributor

vgromfeld commented Feb 24, 2020

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

@vgromfeld vgromfeld added the feature request 📬 A request for new changes to improve functionality label Feb 24, 2020
@ghost
Copy link

ghost commented Feb 24, 2020

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!

@Kyaa-dost Kyaa-dost added the help wanted Issues identified as good community contribution opportunities label Feb 24, 2020
@michael-hawker michael-hawker added this to the 7.0 milestone Mar 2, 2020
@ghost ghost added the in progress 🚧 label Mar 2, 2020
@michael-hawker
Copy link
Member

michael-hawker commented Mar 2, 2020

Removing the Json.NET dependency should help in the future, that's tracked by this item: #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.

@michael-hawker michael-hawker mentioned this issue Mar 11, 2020
7 tasks
ghost pushed a commit that referenced this issue Sep 10, 2020
Created a new Microsoft.Toolkit.Uwp.UI.Controls.Markdown package, moving the MarkdownTextBlock from the Controls package and decoupling the TextToolbar from the MarkDownFormatter.

## Helps with #3145

## PR Type
What kind of change does this PR introduce?
<!-- Please uncomment one or more that apply to this PR. -->

<!-- - Bugfix -->
<!-- - Feature -->
<!-- - Code style update (formatting) -->
- Refactoring
<!-- - Build or CI related changes -->
<!-- - Documentation content changes -->
<!-- - Sample app changes -->
<!-- - Other... Please describe: -->


## What is the current behavior?
Having a dependency on Microsoft.Toolkit.Uwp.UI.Controls pulls too many packages and dependencies.


## What is the new behavior?
Microsoft.Toolkit.Uwp.UI.Controls no longer has a dependency on ColorCode.UWP, nor on the Microsoft.Toolkit.Parsers package.

## PR Checklist

Please check if your PR fulfills the following requirements:

- [X] Tested code with current [supported SDKs](../readme.md#supported)
- [ ] Pull Request has been submitted to the documentation repository [instructions](..\contributing.md#docs). Link: <!-- docs PR link -->
- [X] Sample in sample app has been added / updated (for bug fixes / features)
    - [ ] Icon has been created (if new sample) following the [Thumbnail Style Guide and templates](https://github.com/windows-toolkit/WindowsCommunityToolkit-design-assets)
- [ ] Tests for the changes have been added (for bug fixes / features) (if applicable)
- [X] Header has been added to all new source files (run *build/UpdateHeaders.bat*)
- [ ] Contains **NO** breaking changes

If you are using MarkdownTextBlock, or the TextToolbar with `Format = Format.Markdown`, you will need to add a dependency to the new Microsoft.Toolkit.Uwp.UI.Controls.Markdown. The MarkdownTextBlock implementation is unchanged, but the TextToolbar no longer has a Format property. The markdown parser is now provided just as any other custom parser, and need to be added in Xaml, or code behind. For example:
```xaml
<Page 
...
      xmlns:markDown="using:Microsoft.Toolkit.Uwp.UI.Controls.TextToolbarFormats.MarkDown"
      xmlns:richText="using:Microsoft.Toolkit.Uwp.UI.Controls.TextToolbarFormats.RichText"
...
>
...
<controls:TextToolbar ...>
      <controls:TextToolbar.Formatter>
        <richText:RichTextFormatter />
        <!--<markDown:MarkDownFormatter />-->
        <!--<local:CustomFormatter />-->
      </controls:TextToolbar.Formatter>
</controls:TextToolbar>
...
```
@michael-hawker
Copy link
Member

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

@vgromfeld
Copy link
Contributor Author

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.

@michael-hawker
Copy link
Member

FYI @vgromfeld @JustinXinLiu @rudyhuyn

Obviously if you use multiple packages, the additional overhead starts to minimize with shared dependencies between some of the higher-up packages of Controls. If you just needed one individual package, this gives us a good idea of the overhead that brings.

Here's the whole latest breakdown from the final bit of work we're doing in #3676:

----------------------------------
Extracting Baseline...
Baseline Footprint: 25,908,915 bytes
-----------------------------------------
Microsoft.Toolkit.HighPerformance Additional Footprint: 154,800 bytes
  App Diff: (.exe) = 1,024
  App Diff: (.xml) = 642
  App Diff: (.appxsym) = 26,948
  Size Diff: AppxBundleManifest.xml = 22
  Size Diff: AppxBlockMap.xml = 422
  Size Diff: AppxManifest.xml = 22
  Size Diff: resources.pri = 200
  Size Diff: System.Runtime.CompilerServices.Unsafe.dll = 1,544
  Additional: Microsoft.Bcl.HashCode.dll = 23,112
  Lib (self): Microsoft.Toolkit.HighPerformance.dll = 100,864
-----------------------------------------

Microsoft.Toolkit.Mvvm Additional Footprint: 106,436 bytes
  App Diff: (.exe) = 3,072
  App Diff: (.xml) = 659
  App Diff: (.appxsym) = 17,336
  Size Diff: AppxBundleManifest.xml = 11
  Size Diff: AppxBlockMap.xml = 323
  Size Diff: AppxManifest.xml = 11
  Size Diff: resources.pri = 160
  Size Diff: System.Runtime.CompilerServices.Unsafe.dll = 1,536
  Additional: Microsoft.Bcl.AsyncInterfaces.dll = 20,864
  Lib (self): Microsoft.Toolkit.Mvvm.dll = 62,464
-----------------------------------------

Microsoft.Toolkit.Uwp.Connectivity Additional Footprint: 313,114 bytes
  App Diff: (.exe) = 1,024
  App Diff: (.xml) = 642
  App Diff: (.appxsym) = 52,516
  Size Diff: AppxBundleManifest.xml = 24
  Size Diff: AppxBlockMap.xml = 637
  Size Diff: AppxManifest.xml = 23
  Size Diff: resources.pri = 200
  Size Diff: System.Runtime.CompilerServices.Unsafe.dll = 1,536
  Additional: Microsoft.Toolkit.dll = 96,768
  Lib (self): Microsoft.Toolkit.Uwp.Connectivity.dll = 55,296
  Additional: Microsoft.Toolkit.Uwp.dll = 104,448
-----------------------------------------

Microsoft.Toolkit.Uwp.DeveloperTools Additional Footprint: 51,961 bytes
  App Diff: (.exe) = 3,584
  App Diff: (.xml) = 721
  App Diff: (.appxsym) = 17,188
  Size Diff: AppxBundleManifest.xml = 25
  Size Diff: AppxBlockMap.xml = 409
  Size Diff: AppxManifest.xml = 25
  Size Diff: resources.pri = 3,608
  Lib (self): Microsoft.Toolkit.Uwp.DeveloperTools.xr.xml = 2,337
  Lib (self): Microsoft.Toolkit.Uwp.DeveloperTools.dll = 24,064
-----------------------------------------

Microsoft.Toolkit.Uwp.Input.GazeInteraction Additional Footprint: 79,261 bytes
  App Diff: (.exe) = 6,656
  App Diff: (.xml) = 2,102
  App Diff: (.appxsym) = 21,926
  Size Diff: AppxBundleManifest.xml = 32
  Size Diff: AppxBlockMap.xml = 233
  Size Diff: AppxManifest.xml = 32
  Size Diff: resources.pri = 664
  Lib (self): Microsoft.Toolkit.Uwp.Input.GazeInteraction.dll = 47,616
-----------------------------------------

Microsoft.Toolkit.Uwp.Notifications Additional Footprint: 142,057 bytes
  App Diff: (.exe) = 2,560
  App Diff: (.xml) = 204
  App Diff: (.appxsym) = 29,284
  Size Diff: AppxBundleManifest.xml = 24
  Size Diff: AppxBlockMap.xml = 281
  Size Diff: AppxManifest.xml = 24
  Size Diff: resources.pri = 112
  Lib (self): Microsoft.Toolkit.Uwp.Notifications.dll = 109,568
-----------------------------------------

Microsoft.Toolkit.Uwp.UI.Animations Additional Footprint: 662,544 bytes
  App Diff: (.exe) = 26,624
  App Diff: (.xml) = 2,298
  App Diff: (.appxsym) = 118,491
  Size Diff: AppxBundleManifest.xml = 25
  Size Diff: AppxBlockMap.xml = 1,082
  Size Diff: AppxManifest.xml = 24
  Size Diff: resources.pri = 2,512
  Size Diff: System.Runtime.CompilerServices.Unsafe.dll = 1,536
  Additional: Microsoft.Toolkit.dll = 96,768
  Additional: Microsoft.Toolkit.Uwp.dll = 104,448
  Lib (self): Microsoft.Toolkit.Uwp.UI.Animations.dll = 163,328
  Additional: Microsoft.Toolkit.Uwp.UI.dll = 145,408
-----------------------------------------

Microsoft.Toolkit.Uwp.UI.Behaviors Additional Footprint: 784,995 bytes
  App Diff: (.exe) = 6,144
  App Diff: (.xml) = 1,149
  App Diff: (.appxsym) = 150,234
  Size Diff: AppxBundleManifest.xml = 24
  Size Diff: AppxBlockMap.xml = 1,541
  Size Diff: AppxManifest.xml = 23
  Size Diff: resources.pri = 3,288
  Size Diff: System.Runtime.CompilerServices.Unsafe.dll = 1,536
  Additional: Microsoft.Toolkit.dll = 96,768
  Additional: Microsoft.Toolkit.Uwp.dll = 104,448
  Additional: Microsoft.Toolkit.Uwp.UI.Animations.dll = 163,328
  Lib (self): Microsoft.Toolkit.Uwp.UI.Behaviors.dll = 27,648
  Additional: Microsoft.Toolkit.Uwp.UI.dll = 145,408
  Additional: Microsoft.Xaml.Interactions.dll = 49,920
  Additional: Microsoft.Xaml.Interactivity.dll = 33,536
-----------------------------------------

Microsoft.Toolkit.Uwp.UI.Controls.Core Additional Footprint: 1,280,989 bytes
  App Diff: (.exe) = 12,800
  App Diff: (.xml) = 3,300
  App Diff: (.appxsym) = 197,485
  Size Diff: AppxBundleManifest.xml = 28
  Size Diff: AppxBlockMap.xml = 1,975
  Size Diff: AppxManifest.xml = 27
  Size Diff: resources.pri = 141,408
  Size Diff: System.Runtime.CompilerServices.Unsafe.dll = 1,536
  Lib (self): Microsoft.Toolkit.Uwp.UI.Controls.Core.xr.xml = 39,230
  Additional: Microsoft.Toolkit.dll = 96,768
  Additional: Microsoft.Toolkit.Uwp.dll = 104,448
  Lib (self): Microsoft.Toolkit.Uwp.UI.Controls.Core.dll = 494,080
  Additional: Microsoft.Toolkit.Uwp.UI.Controls.Primitives.dll = 42,496
  Additional: Microsoft.Toolkit.Uwp.UI.dll = 145,408
-----------------------------------------

Microsoft.Toolkit.Uwp.UI.Controls.DataGrid Additional Footprint: 653,249 bytes
  App Diff: (.exe) = 66,560
  App Diff: (.xml) = 4,297
  App Diff: (.appxsym) = 120,731
  Size Diff: AppxBundleManifest.xml = 32
  Size Diff: AppxBlockMap.xml = 953
  Size Diff: AppxManifest.xml = 31
  Size Diff: resources.pri = 27,400
  Lib (self): Microsoft.Toolkit.Uwp.UI.Controls.DataGrid.xr.xml = 9,821
  Lib (self): Microsoft.Toolkit.Uwp.UI.Controls.DataGrid.dll = 423,424
-----------------------------------------

Microsoft.Toolkit.Uwp.UI.Controls.Layout Additional Footprint: 306,274 bytes
  App Diff: (.exe) = 18,944
  App Diff: (.xml) = 1,861
  App Diff: (.appxsym) = 24,736
  Size Diff: AppxBundleManifest.xml = 30
  Size Diff: AppxBlockMap.xml = 586
  Size Diff: AppxManifest.xml = 29
  Size Diff: resources.pri = 1,648
  Lib (self): Microsoft.Toolkit.Uwp.UI.Controls.Layout.dll = 21,504
  Additional: Microsoft.UI.Xaml.winmd = 236,936
-----------------------------------------

Microsoft.Toolkit.Uwp.UI.Controls.Markdown Additional Footprint: 1,986,347 bytes
  App Diff: (.exe) = 44,032
  App Diff: (.xml) = 1,895
  App Diff: (.appxsym) = 299,089
  Size Diff: AppxBundleManifest.xml = 32
  Size Diff: AppxBlockMap.xml = 3,375
  Size Diff: AppxManifest.xml = 207
  Size Diff: resources.pri = 145,336
  Size Diff: System.Runtime.CompilerServices.Unsafe.dll = 1,536
  Additional: Microsoft.Toolkit.Uwp.UI.Controls.Core.xr.xml = 39,230
  Lib (self): Microsoft.Toolkit.Uwp.UI.Controls.Markdown.xr.xml = 4,311
  Additional: Microsoft.UI.Xaml.winmd = 236,936
  Additional: ColorCode.Core.dll = 103,424
  Additional: ColorCode.UWP.dll = 9,216
  Additional: Microsoft.Toolkit.dll = 96,768
  Additional: Microsoft.Toolkit.Parsers.dll = 86,528
  Additional: Microsoft.Toolkit.Uwp.dll = 104,448
  Additional: Microsoft.Toolkit.Uwp.UI.Controls.Core.dll = 494,080
  Lib (self): Microsoft.Toolkit.Uwp.UI.Controls.Markdown.dll = 128,000
  Additional: Microsoft.Toolkit.Uwp.UI.Controls.Primitives.dll = 42,496
  Additional: Microsoft.Toolkit.Uwp.UI.dll = 145,408
-----------------------------------------

Microsoft.Toolkit.Uwp.UI.Controls.Media Additional Footprint: 2,677,160 bytes
  App Diff: (.exe) = 4,608
  App Diff: (.xml) = 172
  App Diff: (.appxsym) = 110,645
  Size Diff: AppxBundleManifest.xml = 29
  Size Diff: AppxBlockMap.xml = 4,089
  Size Diff: AppxManifest.xml = 12,504
  Size Diff: resources.pri = 16,008
  Size Diff: System.Runtime.CompilerServices.Unsafe.dll = 1,744
  Lib (self): Microsoft.Toolkit.Uwp.UI.Controls.Media.xr.xml = 11,841
  Additional: Microsoft.Bcl.AsyncInterfaces.dll = 21,064
  Additional: Microsoft.Graphics.Canvas.dll = 1,373,576
  Additional: Microsoft.Graphics.Canvas.winmd = 281,472
  Additional: Microsoft.Toolkit.dll = 96,768
  Additional: Microsoft.Toolkit.Uwp.dll = 104,448
  Lib (self): Microsoft.Toolkit.Uwp.UI.Controls.Media.dll = 141,824
  Additional: Microsoft.Toolkit.Uwp.UI.dll = 145,408
  Additional: System.Text.Encodings.Web.dll = 57,720
  Additional: System.Text.Json.dll = 293,240
-----------------------------------------

Microsoft.Toolkit.Uwp.UI.Controls.Primitives Additional Footprint: 486,329 bytes
  App Diff: (.exe) = 3,072
  App Diff: (.xml) = 657
  App Diff: (.appxsym) = 90,372
  Size Diff: AppxBundleManifest.xml = 34
  Size Diff: AppxBlockMap.xml = 961
  Size Diff: AppxManifest.xml = 33
  Size Diff: resources.pri = 544
  Size Diff: System.Runtime.CompilerServices.Unsafe.dll = 1,536
  Additional: Microsoft.Toolkit.dll = 96,768
  Additional: Microsoft.Toolkit.Uwp.dll = 104,448
  Lib (self): Microsoft.Toolkit.Uwp.UI.Controls.Primitives.dll = 42,496
  Additional: Microsoft.Toolkit.Uwp.UI.dll = 145,408
-----------------------------------------

Microsoft.Toolkit.Uwp.UI.Media Additional Footprint: 2,447,684 bytes
  App Diff: (.exe) = 2,048
  App Diff: (.xml) = 1,220
  App Diff: (.appxsym) = 130,947
  Size Diff: AppxBundleManifest.xml = 20
  Size Diff: AppxBlockMap.xml = 3,354
  Size Diff: AppxManifest.xml = 12,495
  Size Diff: resources.pri = 504
  Size Diff: System.Runtime.CompilerServices.Unsafe.dll = 1,536
  Additional: Microsoft.Graphics.Canvas.dll = 1,373,576
  Additional: Microsoft.Graphics.Canvas.winmd = 281,472
  Additional: Microsoft.Toolkit.dll = 96,768
  Additional: Microsoft.Toolkit.Uwp.dll = 104,448
  Additional: Microsoft.Toolkit.Uwp.UI.Animations.dll = 163,328
  Additional: Microsoft.Toolkit.Uwp.UI.dll = 145,408
  Lib (self): Microsoft.Toolkit.Uwp.UI.Media.dll = 130,560
-----------------------------------------

Microsoft.Toolkit.Uwp.UI Additional Footprint: 433,012 bytes
  App Diff: (.exe) = 6,656
  App Diff: (.xml) = 719
  App Diff: (.appxsym) = 76,216
  Size Diff: AppxBundleManifest.xml = 14
  Size Diff: AppxBlockMap.xml = 754
  Size Diff: AppxManifest.xml = 13
  Size Diff: resources.pri = 480
  Size Diff: System.Runtime.CompilerServices.Unsafe.dll = 1,536
  Additional: Microsoft.Toolkit.dll = 96,768
  Additional: Microsoft.Toolkit.Uwp.dll = 104,448
  Lib (self): Microsoft.Toolkit.Uwp.UI.dll = 145,408
-----------------------------------------

Microsoft.Toolkit.Uwp Additional Footprint: 247,956 bytes
  App Diff: (.exe) = 4,096
  App Diff: (.xml) = 264
  App Diff: (.appxsym) = 40,267
  Size Diff: AppxBundleManifest.xml = 10
  Size Diff: AppxBlockMap.xml = 453
  Size Diff: AppxManifest.xml = 10
  Size Diff: resources.pri = 104
  Size Diff: System.Runtime.CompilerServices.Unsafe.dll = 1,536
  Additional: Microsoft.Toolkit.dll = 96,768
  Lib (self): Microsoft.Toolkit.Uwp.dll = 104,448
-----------------------------------------

Microsoft.Toolkit Additional Footprint: 118,717 bytes
  App Diff: (.exe) = 1,024
  App Diff: (.xml) = 638
  App Diff: (.appxsym) = 18,321
  Size Diff: AppxBundleManifest.xml = 6
  Size Diff: AppxBlockMap.xml = 226
  Size Diff: AppxManifest.xml = 6
  Size Diff: resources.pri = 192
  Size Diff: System.Runtime.CompilerServices.Unsafe.dll = 1,536
  Lib (self): Microsoft.Toolkit.dll = 96,768
-----------------------------------------

@vgromfeld
Copy link
Contributor Author

I've rebuilt my sample app with the 7.0.0-preview 4 nuget package and the app's dll size has decreased from 6,171Kb to 1,800Kb (x86) 🎉

@michael-hawker
Copy link
Member

@vgromfeld preview4 was even before some of these refactors, so that's good to hear! There's the latest instructions about grabbing PR packages here.

Build 7.0.0-build.749.ge410992e4e has the new 'Core' package being worked on in #3676, so I'd be curious what different that makes, and if you feel that is acceptable or if we should split 'Core' into 2 packages of roughly half the size each?

@vgromfeld
Copy link
Contributor Author

Hum, when I tried using the Microsoft.Toolkit.Uwp.UI package from 7.0.0-build.749.ge410992e4e the app's dll size is 4,162Kb which is still better than before but not as good as 7.0.0-preview 4 which was 1Mb 🤔

@michael-hawker
Copy link
Member

Hum, when I tried using the Microsoft.Toolkit.Uwp.UI package from 7.0.0-build.749.ge410992e4e the app's dll size is 4,162Kb which is still better than before but not as good as 7.0.0-preview 4 which was 1Mb 🤔

Well, that's confusing... Preview4 added both the Behaviors dependency and System.Text.Json which we've now removed... I mean the UI dll itself is like 150kb only, so I don't see how there could be that big a swing...?

There shouldn't be anything different in the build process between the PR and preview branches, it's the same pipeline...

@vgromfeld
Copy link
Contributor Author

Looking at the content of both binaries, using the 7.0.0-build.749.ge410992e4e package pulls a lot of Xml related types which were not part of preview 4.

I can see System.Xml.*, `System.Runtime.Serialization.Xml*. types in the pdb (using PDB Viewer).

@michael-hawker
Copy link
Member

@vgromfeld hmmm, I wonder if that's because of #3637? I didn't think that using the existing platform stuff should matter to overhead? Is this because we construct one by default, is there a better pattern we can use here if it's not being used?

@michael-hawker
Copy link
Member

@vgromfeld alright, I've been able to dig into this a little bit. I can grab the .NET Native size diff in the Smoke Test script now too. Definitely seems like some of the initial bloat is coming from the Microsoft.Toolkit.Uwp package:

Microsoft.Toolkit.Uwp.UI Additional Max Footprint: 433,716 bytes
  App Diff: (.exe) = 6,656
  App Diff: (.xml) = 719
  App Diff: (.appxsym) = 76,408
  Size Diff: AppxBundleManifest.xml = 14
  Size Diff: AppxBlockMap.xml = 754
  Size Diff: AppxManifest.xml = 13
  Size Diff: resources.pri = 480
  Size Diff: System.Runtime.CompilerServices.Unsafe.dll = 1,536
  Additional: Microsoft.Toolkit.dll = 96,768
  Additional: Microsoft.Toolkit.Uwp.dll = 104,960
  Lib (self): Microsoft.Toolkit.Uwp.UI.dll = 145,408
-----------------------------------------
Microsoft.Toolkit.Uwp.UI Additional Min Footprint: 6,620,382 bytes (i.e. .NET Native comparison)
  App Diff: (.dll) = 6,612,480
  App Diff: (.exe) = 0
  Size Diff: AppxBundleManifest.xml = 14
  Size Diff: AppxBlockMap.xml = 7,395
  Size Diff: AppxManifest.xml = 13
  Size Diff: resources.pri = 480
-----------------------------------------

Microsoft.Toolkit.Uwp Additional Max Footprint: 248,609 bytes
  App Diff: (.exe) = 4,096
  App Diff: (.xml) = 264
  App Diff: (.appxsym) = 40,408
  Size Diff: AppxBundleManifest.xml = 10
  Size Diff: AppxBlockMap.xml = 453
  Size Diff: AppxManifest.xml = 10
  Size Diff: resources.pri = 104
  Size Diff: System.Runtime.CompilerServices.Unsafe.dll = 1,536
  Additional: Microsoft.Toolkit.dll = 96,768
  Lib (self): Microsoft.Toolkit.Uwp.dll = 104,960
-----------------------------------------
Microsoft.Toolkit.Uwp Additional Min Footprint: 5,507,716 bytes
  App Diff: (.dll) = 5,501,440
  App Diff: (.exe) = 0
  Size Diff: AppxBundleManifest.xml = 11
  Size Diff: AppxBlockMap.xml = 6,151
  Size Diff: AppxManifest.xml = 10
  Size Diff: resources.pri = 104
-----------------------------------------

Microsoft.Toolkit Additional Max Footprint: 118,698 bytes
  App Diff: (.exe) = 1,024
  App Diff: (.xml) = 638
  App Diff: (.appxsym) = 18,302
  Size Diff: AppxBundleManifest.xml = 6
  Size Diff: AppxBlockMap.xml = 226
  Size Diff: AppxManifest.xml = 6
  Size Diff: resources.pri = 192
  Size Diff: System.Runtime.CompilerServices.Unsafe.dll = 1,536
  Lib (self): Microsoft.Toolkit.dll = 96,768
-----------------------------------------
Microsoft.Toolkit Additional Min Footprint: 426,638 bytes
  App Diff: (.dll) = 425,984
  App Diff: (.exe) = 0
  Size Diff: AppxBundleManifest.xml = 6
  Size Diff: AppxBlockMap.xml = 450
  Size Diff: AppxManifest.xml = 6
  Size Diff: resources.pri = 192
-----------------------------------------

I'm trying to get the older 7.0.0-preview4 branch to build locally to grab the numbers to compare, but there were minimal changes to this package done between then and now:

image

It's mainly the change we did in #3637, which is a bit more confusing.

I'll see what the numbers show for 7.0.0-preview4, I may have to configure pulling the raw NuGet packages down as building is troublesome since we updated to .NET 5 after that preview so those changes are all missing.

@michael-hawker
Copy link
Member

Took a while as our build system for the Smoke Tests is forcing to use the Nerdbank version, so I had to undo that stuff so I could force a build from the 7.0.0-preview4 nugets, but was able to finally get a proper comparison between the current main and 7.0.0-preview4 (both attached).

Definitely can see the difference in the minimum impact. The main question is to understand why, as I tried commenting out the changes entirely to the JsonObjectSerializer from #3637 and it didn't seem to have an impact...

FootPrintMain.txt
FootPrint7.0.0-preview4.txt

@michael-hawker
Copy link
Member

I just did a quick investigation on C# based Windows Runtime Components (WRC). Converting Microsoft.Toolkit.Uwp to a Windows Runtime Component doesn't take much on a project file, just:

    <OutputType>winmdobj</OutputType>
    <AllowCrossPlatformRetargeting>false</AllowCrossPlatformRetargeting>

However, that introduces 440+ errors that need to be resolved, most of which are individually significant and require breaking changes. It's definitely not something we would tackle for 7.0. And we'd want to think about the pros vs. cons or if we pull out smaller chunks at a time which are more easily transferrable (this may make more sense in the UI package for things like Converters and Triggers, etc...) I also don't know how this world changes for .NET 5+ and C#/WinRT @azchohfi?

Doing some quick tests on relatively empty components, it does appear that a C# WRC is compiled into a winmd and would live outside the application dll. Therefore, it could potentially be more easily shared on the overall footprint of an app. If that WRC references a regular .NET Standard component, it appear that still lives outside of it and is included in the app dll, though the winmd file will still remain separate.

Going to look at seeing if we need the Uwp package as a dependency for the UI package.

@michael-hawker
Copy link
Member

Since generics in the UWP package were difficult, I decided to do some more investigations trying to just pull over the Converters and Triggers from the UI package to a Windows Runtime Component. However, the lack of inheritance and abstract classes made that fairly difficult for some. We were able to maybe relatively easily convert over the DependencyProperty constructs (needs more testing).

In the end though, the winmd produced was only like 40kb and there may be some trimming going on as the one in the AppX folder is only 18kb. I'm not sure where that ends up on disk, so I couldn't test dropping the full winmd in its place to see what would happen. Even then, the impact on the app due to system dependencies via .NET Native still seems to be the larger impact here compared to teasing out bits and pieces within a winmd. Especially with the extra restrictions that places on them?

i.e. If we had something large like the Controls package as whole which could be a winmd, then maybe it would make more sense.

I think we need to understand more of how the new world works in .NET 5+ before making a decision on this front as well.

@Kyaa-dost Kyaa-dost linked a pull request Feb 12, 2021 that will close this issue
8 tasks
@ghost ghost removed the help wanted Issues identified as good community contribution opportunities label Feb 12, 2021
@ghost ghost locked as resolved and limited conversation to collaborators Apr 14, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
feature request 📬 A request for new changes to improve functionality in progress 🚧 In-PR 🚀
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants