Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Investigate Blazor WebAssembly startup performance characteristics #54353

Closed
MackinnonBuck opened this issue Mar 4, 2024 · 3 comments
Closed
Assignees
Labels
area-blazor Includes: Blazor, Razor Components bug This issue describes a behavior which is not expected - a bug. Perf
Milestone

Comments

@MackinnonBuck
Copy link
Member

Even when Blazor WebAssembly assets are cached, the time it takes for a Blazor WebAssembly app to initialize can be significant. We should investigate ways to further optimize Blazor WebAssembly initialization to reduce this startup time.

Some preliminary investigation suggests that Blazor-specific startup (everything that happens after the code in Program.cs starts executing) accounts for at least half the total initialization time.

We should:

  • Add instrumentation to measure how long various initialization stages take
    • Such stages include loading cached assets, initializing the .NET WebAssembly runtime, and many of the steps between the start of the app's entrypoint and the first interactive render
  • Collect traces for Blazor-specific initialization code
  • Given those results, determine what work can be done to minimize WebAssembly startup time
  • Consider benchmarking daily builds so we can track these detailed performance measurements over time

Related issues:

@MackinnonBuck MackinnonBuck added the area-blazor Includes: Blazor, Razor Components label Mar 4, 2024
@mkArtakMSFT mkArtakMSFT added bug This issue describes a behavior which is not expected - a bug. Perf labels Mar 5, 2024
@zubairkhakwani
Copy link

Currently, when using Blazor in InteractiveAuto render mode, the application starts with Blazor Server on the initial load and transitions to WebAssembly once all DLLs are loaded and cached. However, on subsequent requests, it waits for WebAssembly to start, neglecting the benefits of Blazor Server.

To enhance performance and user experience, I suggest implementing a mechanism where the first page load or any subsequent refreshes always utilize Blazor Server, while booting WebAssembly in the background. This approach can mitigate concerns about WebAssembly startup performance, as we can improve it up to a certain extent.

Making this behavior configurable would provide flexibility. Users could choose to wait for WebAssembly to load when the cache is available or opt for Blazor Server on every initial request, even if WebAssembly is downloaded.

By implementing this approach, we can optimize the application's performance and provide users with a smoother transition to WebAssembly while still leveraging the benefits of Blazor Server where applicable.

Would love to hear thoughts and feedback on this proposal!

@mkArtakMSFT
Copy link
Member

Bringing #31877 into the current milestone as @MackinnonBuck 's investigation leads us to believe that this work will bring substantial benefits to startup perf.

@MackinnonBuck
Copy link
Member Author

Here are some results from this investigation:

Add instrumentation to measure how long various initialization stages take... collect traces for Blazor-specific initialization code

By adding the following to the WebAssembly project's .csproj file:

<PropertyGroup>
    <WasmProfilers>browser;</WasmProfilers>
    <WasmBuildNative>true</WasmBuildNative>
</PropertyGroup>

...and adding the following to the webAssembly options in Blazor.start():

configureRuntime: (builder) => {
  builder.withConfig({
    browserProfilerOptions: {},
  });
}

...a recording can be taken in the browser's dev tools "performance" tab and a flame graph will show how long each procedure takes.

Given those results, determine what work can be done to minimize WebAssembly startup time

One of the main contributors to startup time was reflection performed during JSON serialization. This indicated that using the STJ source generator may yield performance benefits.

Consider benchmarking daily builds so we can track these detailed performance measurements over time

In addition to existing Blazor WebAssembly standalone perf tests, we added automated Lighthouse tests earlier this year to see how changes like this affect Lighthouse metrics.

After introducing a change that utilized the STJ source generator during WebAssembly startup, we noticed a WebAssembly startup time improvement of 15-30%. These numbers may vary for larger apps, or apps that do significant work in user code during startup.

Finding a way to eliminate JSON serialization altogether during startup may result in further improvement of startup time (I would conservatively estimate an additional 15% improvement, possibly higher for Blazor Web scenarios because it performs more serialization on startup).

Closing this issue out since the investigation is complete, and we have taken some steps to improve WebAssembly startup performance. We can open other issues to track additional improvements to WebAssembly startup.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-blazor Includes: Blazor, Razor Components bug This issue describes a behavior which is not expected - a bug. Perf
Projects
None yet
Development

No branches or pull requests

3 participants