The DependencyInjection library uses IL Emit and Reflection in order to create service implementations. However, this isn't linker friendly because the ILLinker will trim the constructors from these types, since it doesn't know anyone is using them.
We should annotate the DependencyInjection library with DynamicallyAccessedMembers attributes, so the ILLinker knows to preserve the constructors correctly. This should allow us to remove the Microsoft.Extensions.* assemblies from Blazor's "type granularity" list, and instead fully trim these assemblies, just like the System.* assemblies.
I have a prototype of this here, where the size reduction is decent:
Uncompressed IL file sizes:
- Before 2,425,856 bytes
- After 2,360,320 bytes
Compressed (.br) all file sizes in wwwroot_framework:
- Before 1,464,786 bytes
- After 1,443,696 bytes
We can see a ~20 KB size reduction in the Brotli compressed file sizes with this change.
cc @pranavkm @SteveSandersonMS @joperezr @layomia @davidfowl
The DependencyInjection library uses IL Emit and Reflection in order to create service implementations. However, this isn't linker friendly because the ILLinker will trim the constructors from these types, since it doesn't know anyone is using them.
We should annotate the DependencyInjection library with
DynamicallyAccessedMembersattributes, so the ILLinker knows to preserve the constructors correctly. This should allow us to remove theMicrosoft.Extensions.*assemblies from Blazor's "type granularity" list, and instead fully trim these assemblies, just like theSystem.*assemblies.I have a prototype of this here, where the size reduction is decent:
Uncompressed IL file sizes:
- Before 2,425,856 bytes
- After 2,360,320 bytes
Compressed (.br) all file sizes in wwwroot_framework:
- Before 1,464,786 bytes
- After 1,443,696 bytes
We can see a ~20 KB size reduction in the Brotli compressed file sizes with this change.
cc @pranavkm @SteveSandersonMS @joperezr @layomia @davidfowl