Use force-cache for .wasm files to eliminate revalidation overhead #121641
+10
−4
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Fixes #
Description
.NET 10 introduced a performance regression where Blazor WebAssembly apps revalidate all .wasm files on every page load (HTTP 304), causing 10+ second delays locally and minutes on remote servers. This regressed from .NET 8/9 which used a custom browser cache.
Modified
fetchResource()insrc/mono/browser/runtime/loader/assets.tsto usecache: "force-cache"for .wasm files, allowing the browser to serve from HTTP cache without revalidation. Other assets retaincache: "no-cache"behavior.Customer Impact
Users experience significantly degraded startup performance on every page reload. Production deployments to cloud servers are particularly affected, with load times extending to multiple minutes. This makes .NET 10 Blazor WASM apps effectively unusable compared to .NET 8/9.
Regression
Yes. This is a performance regression introduced in .NET 10 RC1. .NET 8 and 9 did not exhibit this behavior.
Testing
disableNoCacheFetchconfiguration optionRisk
Low. This is a one-line caching policy change for .wasm files only. The fix aligns with standard browser caching practices and was validated by the Blazor team in issue comments. No changes to asset integrity checks or credentials handling.
Original prompt
This section details on the original issue you should resolve
<issue_title>Blazor Web App WASM download performance issues</issue_title>
<issue_description>### Is there an existing issue for this?
Describe the bug
There are too many wasm files being downloaded during startup and every time I reload the browser. It took almost 10 seconds to load all these files in local environment and several minutes to load these files into the browser when deployed to a remote/cloud server.
This happens only in .NET 10 rc1 but not in previous versions (e.g. 9.0/8.0).
Expected Behavior
Must load faster like in .net 8/9
Steps To Reproduce
Compare two simple projects in both .NET 10 and .NET 9/8
Refresh/reload the browser. As you can see in .NET 10 it's download several wasm files and are very slow. This behavior doesn't happen in .NET 9 and .NET 8
Exceptions (if any)
No response
.NET Version
No response
Anything else?
No response</issue_description>
<agent_instructions>Ideally, if we validate our hypothesis, we want to force the
fetchdirective for loading .wasm files in the webassembly runtime to use theforce-cachefetch option.</agent_instructions>Comments on the Issue (you are @copilot in this section)
@javiercn @wendellestradairely thanks for contacting us.During development asset caching is disabled to avoid serving stale assets. In production you should see the files served from cache. In .NET 8.0 and 9.0 we used a custom
browsercache object to avoid the asset download altogether, but that came at a cost of size and complexity.In .NET 10.0 an onwards we simply rely on the browser HTTP cache, which shouldn't show any difference in performance or behavior provided you are publishing in Release mode and running the published app.
During development we take some shortcuts to avoid potentially serving stale assets.
Please publish the app in Release mode, run the published output and let us know if you still have issues in that configuration.</comment_new>
<comment_new>@javiercn
@wendellestradairely what does the
fromcolumn after time say?</comment_new><comment_new>@oroztocil
@wendellestradairely
The errors you see in the console are caused by an unrelated problem with Wasm publish that was introduced in RC2 and reported elsewhere (#63970, dotnet/aspnetcore#64041). This problem is fixed in the latest build.
Could you please try to reproduce your original download issue with the latest RC2 build (currently the same as the latest main)? You can get it from here: https://github.com/dotnet/dotnet/blob/main/docs/builds-table.md </comment_new>
<comment_new>@oroztocil
@wendellestradairely I apologize but a colleague just informed me that a final bit of the Wasm publish fix has not been released yet (pending this PR dotnet/dotnet#2927). If you are willing to re-test the download issue later, I can ping you when a proper public build of the SDK is available.</comment_new>
<comment_new>@oroztocil
@wendellestradairely Sorry for the delay. If you are still interested, can you reproduce your initial performance issue using the final GA release? https://dotnet.microsoft.com/en-us/download/dotnet/10.0</comment_new>
<comment_new>@javiercn
Hi folks.
We ran some tests on our end and we don't see a meaningful difference in results. To explain what is happening here, the browser chooses to send some HTTP requests to revalidate the
.wasmfiles does so in the background. We believe the dev tools here are misleading because the content is served right away from the cache but it shows as 304 in the dev tools because the browser actually revalidates it. Now with that in mind, we want to ask you to run a somewhat simple test in your setups to see if you observe any difference. Note that you shouldn't be looking at the dev tools for this, but at some other metric like TTI or similar. You could use a performance counter in JS to measure the difference in startup time.The following snippet will force the cache and it shows as such on the devtools. Please let us know if this makes any actual observable wall clock time difference in your setups.