-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Description
When trimming a Blazor WASM app, the last usage of Reflection.Emit (after fixing #38678) is coming from System.Text.Json.Serialization.JsonSerializerOptions:
runtime/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.cs
Lines 423 to 438 in d89772a
| internal MemberAccessor MemberAccessorStrategy | |
| { | |
| get | |
| { | |
| if (_memberAccessorStrategy == null) | |
| { | |
| #if NETFRAMEWORK || NETCOREAPP | |
| _memberAccessorStrategy = new ReflectionEmitMemberAccessor(); | |
| #else | |
| _memberAccessorStrategy = new ReflectionMemberAccessor(); | |
| #endif | |
| } | |
| return _memberAccessorStrategy; | |
| } | |
| } |
However, on Mono WASM, RuntimeFeature.IsDynamicCodeCompiled is always false, so using Reflection.Emit is probably a waste, and it brings in a decent amount of code. In my investigations I find it removing ~50KB of IL if we trim this usage of Reflection.Emit.
We should change this code to something more like:
internal MemberAccessor MemberAccessorStrategy
{
get
{
if (_memberAccessorStrategy == null)
{
#if NETFRAMEWORK || NETCOREAPP
if (RuntimeFeature.IsDynamicCodeCompiled)
{
_memberAccessorStrategy = new ReflectionEmitMemberAccessor();
}
else
{
_memberAccessorStrategy = new ReflectionMemberAccessor();
}
#else
_memberAccessorStrategy = new ReflectionMemberAccessor();
#endif
}
return _memberAccessorStrategy;
}
}With changing the code to the above, on a default template Blazor WASM app, I am seeing size savings of:
| Build | Size |
|---|---|
| master | 3,366,912 bytes |
| #38729 | 3,039,232 bytes |
| #38729 + this change | 2,990,080 bytes |
So almost a 50 KB savings by allowing the removing all usages of System.Reflection.Emit.