Skip to content

Preload Blazor WebAssembly resources to improve startup time #58875

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

Closed
4 tasks done
mkArtakMSFT opened this issue Nov 11, 2024 · 3 comments
Closed
4 tasks done

Preload Blazor WebAssembly resources to improve startup time #58875

mkArtakMSFT opened this issue Nov 11, 2024 · 3 comments
Assignees
Labels
area-blazor Includes: Blazor, Razor Components enhancement This issue represents an ask for new feature or an enhancement to an existing one feature-blazor-wasm This issue is related to and / or impacts Blazor WebAssembly Perf Priority:1 Work that is critical for the release, but we could probably ship without triaged
Milestone

Comments

@mkArtakMSFT
Copy link
Member

mkArtakMSFT commented Nov 11, 2024

We want to add preload links for all the files that are on the critical path (dotnet.js, dotnet.runtime.js, dotnet.native.js, dotnet.wasm, boot.js) so the browser can start downloading them eagerly.

In runtime sample we do https://github.com/dotnet/runtime/blob/main/src/mono/sample/wasm/browser-advanced/index.html#L13-L16.

In .NET 9 we have split list of assemblies to "core" (required to started MonoVM) and "others". Preloading core assemblies with lower priority also seems like a good fit.


Implementation plan

  • In WebAssembly SDK identify key assets and add preloading properties to endpoints (rel, as, fetchpriority, crossorigin, integrity)
    • Preload dotnet.js
    • Preload boot config
    • Preload dotnet.*.js
    • Preload dotnet.*.wasm
    • Preload core dlls with lower priority
    • Based on StaticWebAssetProjectMode=Default or OverrideHtmlAssetPlaceholders=true we can determine whether to use fingerprinted endpoint for dotnet.js and dotnet.boot.js
    • Based on measurements the best results provided inlining boot config to dotnet.js & preloading dotnet.js
  • In StaticWebAssets SDK introduce a new placeholder for preloading meta tags in OverrideHtmlAssetPlaceholders=true feature
  • In AspNetCore runtime (EndpointHtmlRenderer.WriteComponentHtml) read preloading properties from endpoints and supply them to the initial response as Link headers
    • Do it only for WebAssembly render mode, not in Auto mode

Additional tasks

  • Consider merging boot config into dotnet.js based if preloading measurements prove it's benefitial
@mkArtakMSFT mkArtakMSFT added area-blazor Includes: Blazor, Razor Components enhancement This issue represents an ask for new feature or an enhancement to an existing one feature-blazor-wasm This issue is related to and / or impacts Blazor WebAssembly Perf triaged labels Nov 11, 2024
@mkArtakMSFT mkArtakMSFT added this to the .NET 10 Planning milestone Nov 11, 2024
@danroth27 danroth27 added the Priority:1 Work that is critical for the release, but we could probably ship without label Jan 13, 2025
@maraf maraf modified the milestones: 10.0-preview3, 10.0-preview4 Mar 19, 2025
@alc-aardvark
Copy link

alc-aardvark commented Mar 22, 2025

I am just commenting to support this, as when running on AWS using a static website hosted in an S3 bucket, then you cannot use the server to pre-render the first page.

I have tried pre-fetching the *.wasm assemblies using the solution from here but this does not work like the Blazor.start() as it doesn't load the assemblies into Webassembly so the Blazor.start still goes to fetch them again (and returns a 304 Not Modified). This is somewhat different behavior from a refreshing an already loaded Blazor app that was started via Blazor.start()

@alc-aardvark
Copy link

I have a statically hosted Blazor Wasm app in AWS S3 and I have used a hidden <div> in index.html to to the Blazor.start(); while the user is reading the landing page content. A button will then toggle the landing page div and the Blazor app div to show the Blazor app.

This works quite well except that on a mobile phone the UI locks up for 1-2 seconds at the end of the WASM load. It would be good if this was done in another thread so that it did not lock up the UI.

During the UI lockup, my carousel stops moving (then continues after the lock up) and button clicks aren't actioned until after the lock up.

@maraf
Copy link
Member

maraf commented Mar 26, 2025

@alc-aardvark Thank you for feedback!

Using a separate thread has a different set of disadvantages. At first it needs to load all scripts separately and it needs to properly set COP headers to allow sharing wasm memory between threads. Using the thread just to start WebAssembly wouldn't probably resulted in better experience.

In one of apps I'm maintaining I had to delay the "startup completed" animation after the work on the main thread finishes. I'm thinking if there is an event that during startup that you could use to stop the carousel

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 enhancement This issue represents an ask for new feature or an enhancement to an existing one feature-blazor-wasm This issue is related to and / or impacts Blazor WebAssembly Perf Priority:1 Work that is critical for the release, but we could probably ship without triaged
Projects
None yet
Development

No branches or pull requests

5 participants