Skip to content

Blazor WebAssembly publishes ship trimmed assemblies that nothing minifies #13261

Description

@yasmoradi

A Blazor WebAssembly publish runs ILLink, which removes the .NET code an app doesn't use. What it leaves is not minified. The JavaScript and CSS of the bit packages already go through esbuild and sass, but the .wasm assemblies still carry:

  • thousands of attributes only the compiler reads ([CompilerGenerated] on accessors, [Nullable], [NullableContext], [NotNullWhen], ...). In the trimmed Bit.BlazorUI of a small app they fill 8,779 of the 10,588 CustomAttribute rows;
  • long compiler-generated names such as <BuildRenderTree>b__12_0 and <OnClickAsync>d__31, about 75K characters in the same assembly;
  • private and internal names nothing reads at runtime.

No existing tool removes this and keeps the result debuggable:

  • trimming and WasmStripILAfterAOT only remove code;
  • obfuscators rename everything, which breaks [Parameter], [JSInvokable] and JSON names, and they don't keep portable pdbs in sync.

A publish-time step after ILLink can remove it. It has to keep the portable pdbs matching, keep public names so logged stack traces stay readable, and leave alone anything the runtime, Blazor or serializers read by name. Measured on bitplatform.dev's WebAssembly client (69 managed .wasm files, 2,094 KB brotli):

brotli
attributes and generated names only, keeping what other libraries read -68 KB (-3.2%)
every non-public name, parameter name and non-public property too -185 KB (-8.8%)

The ceiling is low because IL itself is already compact, and because local variable names live only in the pdb, which isn't downloaded.

Metadata

Metadata

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions