Skip to content

Commit 7bcff9a

Browse files
authored
WebAssembly runtime performance article (#35724)
1 parent a5f6da3 commit 7bcff9a

File tree

3 files changed

+115
-75
lines changed

3 files changed

+115
-75
lines changed
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
---
2+
title: ASP.NET Core Blazor WebAssembly runtime performance
3+
author: guardrex
4+
description: Learn about ASP.NET Core Blazor WebAssembly runtime performance.
5+
monikerRange: '>= aspnetcore-3.1'
6+
ms.author: wpickett
7+
ms.custom: mvc
8+
ms.date: 07/08/2025
9+
uid: blazor/performance/webassembly-runtime-performance
10+
---
11+
# ASP.NET Core Blazor WebAssembly runtime performance
12+
13+
<!-- UPDATE 10.0 - Activate ...
14+
15+
[!INCLUDE[](~/includes/not-latest-version.md)]
16+
17+
-->
18+
19+
This article provides guidance on Blazor WebAssembly runtime performance.
20+
21+
## Potentially reduced performance with Microsoft Edge enhanced security
22+
23+
The Microsoft Edge browser's WebAssembly (WASM) interpreter running in [enhanced security mode](/DeployEdge/microsoft-edge-security-browse-safer) might not yield the same performance as when Blazor is running without enhanced security. If enhanced security mode is enabled and an app's performance is degraded, we recommend adding the site as an [exception](/DeployEdge/microsoft-edge-security-browse-safer#enhanced-security-sites) to opt out of enhanced security mode.
24+
25+
:::moniker range=">= aspnetcore-8.0"
26+
27+
## Trim .NET IL after ahead-of-time (AOT) compilation
28+
29+
The `WasmStripILAfterAOT` MSBuild option enables removing the .NET Intermediate Language (IL) for compiled methods after performing AOT compilation to WebAssembly, which reduces the size of the `_framework` folder.
30+
31+
In the app's project file:
32+
33+
```xml
34+
<PropertyGroup>
35+
<RunAOTCompilation>true</RunAOTCompilation>
36+
<WasmStripILAfterAOT>true</WasmStripILAfterAOT>
37+
</PropertyGroup>
38+
```
39+
40+
This setting trims away the IL code for most compiled methods, including methods from libraries and methods in the app. Not all compiled methods can be trimmed, as some are still required by the .NET interpreter at runtime.
41+
42+
To report a problem with the trimming option, [open an issue on the `dotnet/runtime` GitHub repository](https://github.com/dotnet/runtime/issues).
43+
44+
Disable the trimming property if it prevents your app from running normally:
45+
46+
```xml
47+
<WasmStripILAfterAOT>false</WasmStripILAfterAOT>
48+
```
49+
50+
:::moniker-end
51+
52+
## Heap size for some mobile device browsers
53+
54+
When building a Blazor app that runs on the client and targets mobile device browsers, especially Safari on iOS, decreasing the maximum memory for the app with the MSBuild property `EmccMaximumHeapSize` may be required. For more information, see <xref:blazor/host-and-deploy/webassembly/index#decrease-maximum-heap-size-for-some-mobile-device-browsers>.
55+
56+
## Runtime relinking
57+
58+
One of the largest parts of a Blazor WebAssembly app is the WebAssembly-based .NET runtime (`dotnet.wasm`) that the browser must download when the app is first accessed by a user's browser. Relinking the .NET WebAssembly runtime trims unused runtime code and thus improves download speed.
59+
60+
Runtime relinking requires installation of the .NET WebAssembly build tools. For more information, see <xref:blazor/tooling#net-webassembly-build-tools>.
61+
62+
With the .NET WebAssembly build tools installed, runtime relinking is performed automatically when an app is **published** in the `Release` configuration. The size reduction is particularly dramatic when disabling globalization. For more information, see <xref:blazor/globalization-localization#invariant-globalization>.
63+
64+
> [!IMPORTANT]
65+
> Runtime relinking trims class instance JavaScript-invokable .NET methods unless they're protected. For more information, see <xref:blazor/js-interop/call-dotnet-from-javascript#avoid-trimming-javascript-invokable-net-methods>.
66+
67+
## Single Instruction, Multiple Data (SIMD)
68+
69+
:::moniker range=">= aspnetcore-8.0"
70+
71+
Blazor uses [WebAssembly Single Instruction, Multiple Data (SIMD)](https://wikipedia.org/wiki/Single_instruction,_multiple_data) to improve the throughput of vectorized computations by performing an operation on multiple pieces of data in parallel using a single instruction.
72+
73+
To disable SIMD, for example when targeting old browsers or browsers on mobile devices that don't support SIMD, set the `<WasmEnableSIMD>` property to `false` in the app's project file (`.csproj`):
74+
75+
```xml
76+
<PropertyGroup>
77+
<WasmEnableSIMD>false</WasmEnableSIMD>
78+
</PropertyGroup>
79+
```
80+
81+
For more information, see [Configuring and hosting .NET WebAssembly applications: SIMD - Single instruction, multiple data](https://aka.ms/dotnet-wasm-features#simd---single-instruction-multiple-data) and note that the guidance isn't versioned and applies to the latest public release.
82+
83+
:::moniker-end
84+
85+
:::moniker range="< aspnetcore-8.0"
86+
87+
Blazor uses [WebAssembly Single Instruction, Multiple Data (SIMD)](https://wikipedia.org/wiki/Single_instruction,_multiple_data) to improve the throughput of vectorized computations by performing an operation on multiple pieces of data in parallel using a single instruction.
88+
89+
To enable SIMD, add the `<WasmEnableSIMD>` property set to `true` in the app's project file (`.csproj`):
90+
91+
```xml
92+
<PropertyGroup>
93+
<WasmEnableSIMD>true</WasmEnableSIMD>
94+
</PropertyGroup>
95+
```
96+
97+
For more information, see [Configuring and hosting .NET WebAssembly applications: SIMD - Single instruction, multiple data](https://aka.ms/dotnet-wasm-features#simd---single-instruction-multiple-data) and note that the guidance isn't versioned and applies to the latest public release.
98+
99+
:::moniker-end
100+
101+
## Additional resources
102+
103+
* <xref:blazor/performance/webassembly-browser-developer-tools>
104+
* <xref:blazor/performance/webassembly-event-pipe>
105+
* [What diagnostic tools are available in .NET Core?](/dotnet/core/diagnostics/)
106+
* [.NET diagnostic tools](/dotnet/core/diagnostics/tools-overview)

aspnetcore/blazor/webassembly-build-tools-and-aot.md

Lines changed: 7 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,6 @@ uid: blazor/tooling/webassembly
1414

1515
This article describes the build tools for standalone Blazor WebAssembly apps and how to compile an app ahead of deployment with ahead-of-time (AOT) compilation.
1616

17-
Although the article primarily focuses on standalone Blazor WebAssembly apps, the section on [heap size for some mobile device browsers](#heap-size-for-some-mobile-device-browsers) also applies to the client-side project (`.Client`) of a Blazor Web App.
18-
1917
## .NET WebAssembly build tools
2018

2119
The .NET WebAssembly build tools are based on [Emscripten](https://emscripten.org/), a compiler toolchain for the web platform. To install the build tools, use ***either*** of the following approaches:
@@ -80,81 +78,14 @@ The size of an AOT-compiled Blazor WebAssembly app is generally larger than the
8078
> [!NOTE]
8179
> For [Mono](https://github.com/mono/mono)/WebAssembly MSBuild properties and targets, see [`WasmApp.Common.targets` (`dotnet/runtime` GitHub repository)](https://github.com/dotnet/runtime/blob/main/src/mono/wasm/build/WasmApp.Common.targets). Official documentation for common MSBuild properties is planned per [Document blazor msbuild configuration options (`dotnet/docs` #27395)](https://github.com/dotnet/docs/issues/27395).
8280
83-
:::moniker range=">= aspnetcore-8.0"
84-
85-
## Trim .NET IL after ahead-of-time (AOT) compilation
86-
87-
The `WasmStripILAfterAOT` MSBuild option enables removing the .NET Intermediate Language (IL) for compiled methods after performing AOT compilation to WebAssembly, which reduces the size of the `_framework` folder.
88-
89-
In the app's project file:
90-
91-
```xml
92-
<PropertyGroup>
93-
<RunAOTCompilation>true</RunAOTCompilation>
94-
<WasmStripILAfterAOT>true</WasmStripILAfterAOT>
95-
</PropertyGroup>
96-
```
97-
98-
This setting trims away the IL code for most compiled methods, including methods from libraries and methods in the app. Not all compiled methods can be trimmed, as some are still required by the .NET interpreter at runtime.
99-
100-
To report a problem with the trimming option, [open an issue on the `dotnet/runtime` GitHub repository](https://github.com/dotnet/runtime/issues).
101-
102-
Disable the trimming property if it prevents your app from running normally:
103-
104-
```xml
105-
<WasmStripILAfterAOT>false</WasmStripILAfterAOT>
106-
```
107-
108-
:::moniker-end
109-
110-
## Heap size for some mobile device browsers
111-
112-
When building a Blazor app that runs on the client and targets mobile device browsers, especially Safari on iOS, decreasing the maximum memory for the app with the MSBuild property `EmccMaximumHeapSize` may be required. For more information, see <xref:blazor/host-and-deploy/webassembly/index#decrease-maximum-heap-size-for-some-mobile-device-browsers>.
113-
114-
## Runtime relinking
115-
116-
One of the largest parts of a Blazor WebAssembly app is the WebAssembly-based .NET runtime (`dotnet.wasm`) that the browser must download when the app is first accessed by a user's browser. Relinking the .NET WebAssembly runtime trims unused runtime code and thus improves download speed.
117-
118-
Runtime relinking requires installation of the .NET WebAssembly build tools. For more information, see <xref:blazor/tooling#net-webassembly-build-tools>.
119-
120-
With the .NET WebAssembly build tools installed, runtime relinking is performed automatically when an app is **published** in the `Release` configuration. The size reduction is particularly dramatic when disabling globalization. For more information, see <xref:blazor/globalization-localization#invariant-globalization>.
81+
## Performance
12182

122-
> [!IMPORTANT]
123-
> Runtime relinking trims class instance JavaScript-invokable .NET methods unless they're protected. For more information, see <xref:blazor/js-interop/call-dotnet-from-javascript#avoid-trimming-javascript-invokable-net-methods>.
83+
For performance guidance, see <xref:blazor/performance/webassembly-runtime-performance>:
12484

125-
## Single Instruction, Multiple Data (SIMD)
126-
127-
:::moniker range=">= aspnetcore-8.0"
128-
129-
Blazor uses [WebAssembly Single Instruction, Multiple Data (SIMD)](https://wikipedia.org/wiki/Single_instruction,_multiple_data) to improve the throughput of vectorized computations by performing an operation on multiple pieces of data in parallel using a single instruction.
130-
131-
To disable SIMD, for example when targeting old browsers or browsers on mobile devices that don't support SIMD, set the `<WasmEnableSIMD>` property to `false` in the app's project file (`.csproj`):
132-
133-
```xml
134-
<PropertyGroup>
135-
<WasmEnableSIMD>false</WasmEnableSIMD>
136-
</PropertyGroup>
137-
```
138-
139-
For more information, see [Configuring and hosting .NET WebAssembly applications: SIMD - Single instruction, multiple data](https://aka.ms/dotnet-wasm-features#simd---single-instruction-multiple-data) and note that the guidance isn't versioned and applies to the latest public release.
140-
141-
:::moniker-end
142-
143-
:::moniker range="< aspnetcore-8.0"
144-
145-
Blazor uses [WebAssembly Single Instruction, Multiple Data (SIMD)](https://wikipedia.org/wiki/Single_instruction,_multiple_data) to improve the throughput of vectorized computations by performing an operation on multiple pieces of data in parallel using a single instruction.
146-
147-
To enable SIMD, add the `<WasmEnableSIMD>` property set to `true` in the app's project file (`.csproj`):
148-
149-
```xml
150-
<PropertyGroup>
151-
<WasmEnableSIMD>true</WasmEnableSIMD>
152-
</PropertyGroup>
153-
```
154-
155-
For more information, see [Configuring and hosting .NET WebAssembly applications: SIMD - Single instruction, multiple data](https://aka.ms/dotnet-wasm-features#simd---single-instruction-multiple-data) and note that the guidance isn't versioned and applies to the latest public release.
156-
157-
:::moniker-end
85+
* Heap size for some mobile device browsers
86+
* Runtime relinking
87+
* Single Instruction, Multiple Data (SIMD)
88+
* Trim .NET IL after ahead-of-time (AOT) compilation (.NET 8 or later)
15889

15990
## Exception handling
16091

@@ -189,5 +120,6 @@ For more information, see the following resources:
189120

190121
## Additional resources
191122

123+
* <xref:blazor/performance/webassembly-runtime-performance>
192124
* <xref:blazor/webassembly-native-dependencies>
193125
* [Webcil packaging format for .NET assemblies](xref:blazor/host-and-deploy/webassembly/index#webcil-packaging-format-for-net-assemblies)

aspnetcore/toc.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -660,6 +660,8 @@ items:
660660
uid: blazor/performance/app-download-size
661661
- name: JavaScript interop
662662
uid: blazor/performance/js-interop
663+
- name: WebAssembly runtime performance
664+
uid: blazor/performance/webassembly-runtime-performance
663665
- name: WebAssembly browser developer tools diagnostics
664666
uid: blazor/performance/webassembly-browser-developer-tools
665667
- name: WebAssembly Event Pipe diagnostics

0 commit comments

Comments
 (0)