Repository navigation
Performance profiling for WebAssembly #76316
Copy link
Copy link
Labels
Priority:0Work that we can't release withoutWork that we can't release withoutarch-wasmWebAssembly architectureWebAssembly architecturearea-Diagnostics-monoenhancementProduct code improvement that does NOT require public API changes/additionsProduct code improvement that does NOT require public API changes/additionstrackingThis issue is tracking the completion of other related issues.This issue is tracking the completion of other related issues.
Milestone
Description
Net 10 goals - single threaded Event Pipe and Diagnostic server
- gc heap dump, counters, CPU sampling
- implement single-threaded DS native code
- single threaded managed
AggregationManagerandEventPipeEventDispatcher - implement single-threaded sample profiler (interp, AOT, jiterp)
- implement JavaScript API for triggering trace
- implement WebSocket transport for EP
- Documentation [Pre4] Performance profiling for Blazor WebAssembly apps AspNetCore.Docs#35230
- trigger re-build with
<WasmPerfTracing />change - fix timeouts in
ds-routerfor WebSockets [dsrouter] fix web socket startup diagnostics#5121 - WBT and manual tests [browser] EP testing #114232
Net 10 nice to have
- include ds-router in the dev-server, so that the IPC channel is visible on the local machine
- explore how .nettrace output could be used for PGO AOT in Mono
- click thru symbols in the trace to C# code in VS
- optimize sampling profiler
- simplify browser
<WasmProfilers>browser</WasmProfilers>andconfig.browserProfilerOptions -
Timing-Allow-Originin the devtools
Future goals
- propagate from the WASM client to the server side open telemetry
- integration with VS or VS code
- make multi-threaded event pipe also work
- annotate Mono AOT with event pipe events
-
FRAME_TYPE_IL_STATE
-
- annotate AOT/Interp transitions
- annotate JS interop with event pipe events
- use stats about Interp of runtime libraries to bring more intrinsic methods to Interp
- propagate event pipe events as performance.mark() and performance.measure()
- optional, configurable
- HTTP header Timing-Allow-Origin
- propagate browser events as event pipe events
- Add a way for JavaScript to push events to EventSources.
- VS integration
- Refactor runtime startup to allow the diagnostic server to async pause the browser thread.
Non-goals
- (debugging of) full memory dump - the layout of WASM linear memory is significantly different from other OSs. Also it doesn't capture WASM stack trace, just shadow stack.
- DS/EP and Mono profilers at the same time
- Anything based on
DiagnosticCounterlikeRuntimeEventSourceandCounterGroup, keepUnsupportedOSPlatform("browser")
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
Priority:0Work that we can't release withoutWork that we can't release withoutarch-wasmWebAssembly architectureWebAssembly architecturearea-Diagnostics-monoenhancementProduct code improvement that does NOT require public API changes/additionsProduct code improvement that does NOT require public API changes/additionstrackingThis issue is tracking the completion of other related issues.This issue is tracking the completion of other related issues.
Activity
Stamo-Gochev commentedon Nov 5, 2020
@SteveSandersonMS Can you share more information where this profiler can be found? I see that it is internal, but I can try to rebuild the source code on my side to expose it in some way as I want to debug a wasm app for performance reasons. I have no expectations for it to be working as you mentioned it is targeting 6.0 or later, but I can give it a try for testing purposes.
Stamo-Gochev commentedon Nov 17, 2020
@SteveSandersonMS Any updates?
SteveSandersonMS commentedon Nov 17, 2020
The experimental code we used is in https://github.com/dotnet/runtime/tree/stevesa/hierarchical-profile, however it's not intended for external use, hence there's no information about how to build or use it, or how to understand any data it collects, and it most likely no longer works with current builds of the runtime.
szalapski commentedon May 12, 2021
Would like to see a way to profile Blazor on the client, with an eye toward optimizing performance. Main scenario: I just clicked on an item and it worked 20 seconds before I can see the new UI, and I am quite certain it is not due to download time/network latency; what's taking so long that I should try to optimize?
jirisykora83 commentedon Mar 18, 2022
@SteveSandersonMS Any updates?
jirisykora83 commentedon Mar 18, 2022
I face similar issue and one workround is create
BaseComponentadd it to_Imports.razoras base class for every component@inherits XXX.BaseComponentand then use component live cycle withhttps://developer.mozilla.org/en-US/docs/Web/API/console/timethis give me at least some insight.This is inspired by
https://remibou.github.io/Profiling-in-Blazor/console.time produce some sort of flamegraph in chrome. This is nowhere near the dev experience with full .NET profiler of course.
MertUssakliMSFT commentedon Apr 22, 2022
If there was at least a way to relate compiled
wasm-functionss you see in the Edge profiler back to .NET code symbols, that would be a huge step forward! I can profile and see CPU-heavy workload causing UI delays, but it is impossible to debug it back to what part of the code would need optimization.Chris-D-Turk commentedon May 2, 2022
@MertUssakliMSFT you can actually see the real method-names if you enable AOT compilation in your csproj:
But the build takes a very long time with this config - ~10min for a new blazor wasm solution on my machine.
Maybe you can speed up the build, if your strip unused assemblies - but I don't know how to do this.
MertUssakliMSFT commentedon May 2, 2022
@Chris-D-Turk, cool tip -- will keep this in mind the next time I need to do perf profiling.
Does it work in Release/Ship as well as Debug?
Chris-D-Turk commentedon May 3, 2022
@MertUssakliMSFT yes, it works for both debug and release builds
zHaytam commentedon Aug 28, 2022
Any news about this?
41 remaining items
EliseoDiegoViola commentedon Nov 25, 2024
Any news about this? AOT needs to be a release build only, making debugging annoying.
What are exactly the combination of flags and code that you need to use for it to work on NET 9?
Edit : I partially made it work without AOT as @pavelsavara recommended. Sadly in my Web App, is unusable. Memory usage goes up like crazy for no good reason and chrome crashes. Firefox can go up indefinitely until the app becomes so slow that it cant be of any usage anymore. In an attempt to find the culprit I tried to deactivate different plugins to see what happens, Serilog seems to be doing something, and Fluxor as well. Still not sure what they are doing that makes the app behave like that.
MikiraSora commentedon Nov 28, 2024
Same problem in my Avalonia browser.


coder-johnz commentedon Jan 16, 2025
I have a Blazor Webassembly App that need keep running in browser for long time.
When I upgrade the App from .net8 to .net9, the browser memory usage increases from 200MB to nearly 1GB in 1 day, and up to nearly 2GB in 2days. I only can let user to refresh the browser window when the App becomes slow. Maybe need refresh browser once a day.
When I downgrade the App to .net8, no other code changes, the browser memory usage only increases from 200MB to 300MB in 2 days.
I don't know why the Blazor Webassembly App memory usage goes up so quickly in .net9, maybe is memory leak. But I don't know how to address this problem.
As shown below, the App published with .net8 Release Mode is running 3 days and the memory usage is about 300MB, but the same App published with .net9 Release Mode is running less than 1 day and the memory usage is about 760MB

pavelsavara commentedon Feb 17, 2025
Yes :) #112352
I'm working on making the sampling profiler to actually take samples, rather than every single method enter/leave event.
@MikiraSora @EliseoDiegoViola could you please create repro project with Avalonia for me to try with new runtime bits ? Thanks.
This could be problems related to bad memory ratio and address space fragmentation in Net9.
I think I fixed it here for Net10. #108512
@coder-johnz Net10 Preview 1 would be out any day now. Please test it and let me know.
[dsrouter] fix web socket startup (#5121)