.putty P1DocsWeb Development
Related
Upgrading Your .NET WebAssembly App to .NET 10: A Step-by-Step GuideSelf-Hosters Rejoice: New Dashboard Eliminates the Pain of Remembering IP Addresses and PortsAdvancing Semantic Data: The Block Protocol and the Future of Structured Web ContentReact Native 0.80 Overhauls JavaScript API: Deep Imports Deprecated, Strict TypeScript ArrivesMastering JavaScript Startup Performance with V8's Explicit Compile Hints7 Ways Explicit Compile Hints Supercharge V8 JavaScript StartupBuilding Apple’s Vision Pro Scrolly Animation with Pure CSS: Q&AWeb Developer Curates Top CSS Color Palettes After Abandoning Tailwind

Copilot Studio's Leap to .NET 10: WebAssembly Performance Gains

Last updated: 2026-05-10 06:21:29 · Web Development

When Microsoft's Copilot Studio team shared their journey of running C# in the browser via .NET WebAssembly, they highlighted the performance jumps from .NET 6 to .NET 8. Now, they've taken another leap forward by upgrading their WebAssembly engine to .NET 10. This upgrade brought smoother deployment processes, smaller outputs, and automatic asset integrity checks. Here, we break down the key questions about this migration and what it means for performance and developer experience.

1. Why did Copilot Studio upgrade to .NET 10 for WebAssembly?

The primary motivation was to leverage performance and deployment improvements baked into .NET 10. After seeing significant gains when moving from .NET 6 to .NET 8, the team wanted to stay current. .NET 10 introduced automatic fingerprinting of WebAssembly assets, which eliminates the need for custom scripts to handle caching and integrity. Additionally, WasmStripILAfterAOT became default, reducing the size of AOT-compiled outputs. These changes directly impact startup time and packaging efficiency for Copilot Studio, which already uses a dual-engine approach (JIT for fast start, AOT for steady-state performance). Upgrading allowed them to remove manual workarounds and simplify their build pipeline.

Copilot Studio's Leap to .NET 10: WebAssembly Performance Gains
Source: devblogs.microsoft.com

2. How smooth was the upgrade from .NET 8 to .NET 10?

The upgrade process was remarkably straightforward. According to the team, moving an existing .NET 8 WebAssembly app to .NET 10 primarily involves updating the target framework in the .csproj files and ensuring that all dependencies remain compatible. For Copilot Studio, this was exactly how the migration unfolded, and the .NET 10 build is now running in production. No major code overhauls were needed, thanks to backward compatibility. The team noted that the biggest changes were removing custom scripts (like the file-renaming PowerShell script) rather than adding new code. This highlights how .NET 10 makes it easier to adopt modern WebAssembly features without breaking existing logic.

3. What is automatic fingerprinting and how does it simplify deployment?

Automatic fingerprinting is a new feature in .NET 10 that adds a unique identifier to each WebAssembly asset's filename during publishing. This provides automatic cache-busting and integrity guarantees, so browsers won't serve stale files and can verify files haven't been tampered with. Before this feature, Copilot Studio had to:

  • Read the blazor.boot.json manifest to list all assets.
  • Run a custom PowerShell script to rename each file with a SHA256 hash.
  • Pass an explicit integrity argument from JavaScript when fetching each resource.

With .NET 10, all those manual steps are eliminated. Resources are imported directly from dotnet.js, fingerprints are part of published filenames, and integrity validation happens automatically. The Copilot Studio team deleted their custom renaming script and removed the integrity parameter from the client-side loader, simplifying both code and deployment.

4. What is WasmStripILAfterAOT and why does it matter?

WasmStripILAfterAOT is an optimization that removes the original Intermediate Language (IL) from assemblies that have been ahead-of-time compiled to WebAssembly. Since the IL is no longer needed at runtime, stripping it reduces the download size. In .NET 8, this setting existed but was disabled by default. With .NET 10, it is enabled by default for AOT builds. This directly benefits applications like Copilot Studio that ship both JIT and AOT engines. However, because stripping the IL changes the assembly contents, files that were previously bit-for-bit identical between JIT and AOT modes may no longer match. This affects deduplication strategies. The team accounts for this by carefully managing which files are shared between the two modes. Overall, the reduction in size leads to faster downloads and better startup performance.

Copilot Studio's Leap to .NET 10: WebAssembly Performance Gains
Source: devblogs.microsoft.com

5. How does Copilot Studio combine JIT and AOT engines for optimal performance?

Copilot Studio employs a dual-engine packaging strategy to get the best of both worlds: fast startup and high execution speed. They ship a single NPM package that contains both a JIT engine (for quick initial load) and an AOT engine (for maximum runtime performance). At runtime, both engines are loaded in parallel. The JIT engine handles the first user interactions, allowing the app to become usable almost instantly. Meanwhile, the AOT engine finishes compiling in the background. Once ready, control is handed off to the AOT engine for smoother, faster operation. To keep the package size minimal, files that are identical between the two modes are deduplicated. With .NET 10's WasmStripILAfterAOT, fewer files can be shared because the AOT assemblies lose their IL, but the team's advanced packaging handles this gracefully.

6. Is there a tip for loading the .NET WASM runtime in a WebWorker?

Yes. If you are loading the .NET WebAssembly runtime inside a WebWorker context, you need to set dotnetSidecar = true when initializing the runtime. This ensures proper initialization in a worker environment. The Copilot Studio team shared this tip as part of their migration experience. It's a small but important detail that can prevent subtle bugs when using workers for background tasks or offloading heavy computation. Following this recommendation helps maintain stability and performance in multi-threaded WebAssembly scenarios.