aspnetcore
aspnetcore copied to clipboard
Improve the load time performance of Blazor WebAssembly apps on low-end mobile devices
We've been hearing reports from users that load performance of Blazor WebAssembly apps on low-end mobile devices can be very slow. For example, this user on Twitter reported "bootstrapping is very slow on low-end mobile devices (~10s), caching doesn't help this". We should investigate where the time is being spent on these devices and evaluate options for improvement.
- If the issue is WASM compilation time, that's on the browser to improve.
- If the issue is .NET runtime startup time, preinitialization might help.
- Perhaps we could also cache the preinitialized results with a snapshot of the memory.
- Or maybe these apps are doing something dynamic on startup that's slow.
The first step is to collect some performance profiles. Any help is appreciated! 🙏
Some more examples of this feedback:
https://www.reddit.com/r/Blazor/comments/iorby5/why_is_blazor_loading_so_long/ https://twitter.com/lupusa1/status/1260309165777526784: "I mostly work on blazor wasm and it is slow on mobile, so for now I try to be prioritized to desktop solutions." https://twitter.com/Savaged_US/status/1115369807019425793 - "Blazor and dotnet are just too slow for now (especially on low-power mobile devices)" https://twitter.com/Tibcsi_/status/1304509087598682116: "Blazor webassembly is still slow on a mid range mobile"
Another report of 15s load time on mobile in this issue: https://github.com/dotnet/aspnetcore/issues/41909
I experience this as well on my oldest iPad (5th gen) - refreshing is still slow (~5-7s of pure loading), so caching is not helping. Nothing fancy in the app. How can we help profile this?
Hi Team,
I have a .Net 6 Blazor WASM app with Server Hosted Code. Before Publishing the APP I have added a few Config lines in the project file like this:-
-
-
<TargetFramework>net6.0</TargetFramework>
-
<BlazorEnableTimeZoneSupport>false</BlazorEnableTimeZoneSupport>
-
<BlazorWebAssemblyPreserveCollationData>false</BlazorWebAssemblyPreserveCollationData>
-
<PublishTrimmed>true</PublishTrimmed>
-
<BlazorEnableCompression>true</BlazorEnableCompression>
-
<InvariantGlobalization>true</InvariantGlobalization>
-
<TrimMode>link</TrimMode>
-
<!--<RunAOTCompilation>true</RunAOTCompilation>-->
and Added the Brotli Compression Decoce.js file and some code on the Index.html Page. Now my APP downloads only 1.5 MB of resources and Its loads into 1.5 Secs. SO I have Optimized my app using these settings.
If I am anything missing Please suggest me.
Thanks
@mandeep-sps The problem occurs on older devices. Use throttling and do more tests
Is this normal? I am testing my own application and I've done all the required things: do not use AOT (bigger files), use brotli (dynamic and static), use http3 and http2, etc... and I've got the load times of the app on my dev machine to be around 2.5 s which is acceptable. But where I am seeing the biggest issue is here:
So Blazor finishes loading its files at the 400 ms mark, but the first application request is ran a whole second later:
So is it normal for blazor to take more than a second in starting up? It feels awfully long tbh.
For my Blazor WASM app initial loading is taking 5-10 seconds which is bad enough but on click events from buttons are taking around 2 seconds to fire when accessing the site from a mobile device and often not firing at all resulting in a user having to repeatedly press buttons to get something to happen (doesn't happen from a PC web browser) which is obviously making the app extremely sluggish to use. I would understand if these buttons were submitting data to the server, but when they only trigger a modal to pop up with everything happening locally to the client, I would expect this to be a lot faster.
@ScottKane For the slow event firing issues your seeing, could you please open a separate issue with the specs of the devices where you see this problem including the browser version and a repro project that demonstrates the performance issue?
@danroth27 is the delay of about a second between Blazor assemblies downloading and the app starting its function normal? (see above: https://github.com/dotnet/aspnetcore/issues/42284#issuecomment-1181850985)
@danroth27 I opened https://github.com/dotnet/aspnetcore/issues/43090 for this, I'm currently rebuilding the client from scratch to figure at at what point the performance dies. So far the only thing I can point to causing it is CascadingValue Value="_hubConnection"
as the new client doesn't have that yet and seems to be performing fine even without AOT
A lot of complaints are about the initial start speed because of several MBs of runtime DLLs that must be first downloaded while on slow mobile networks.
Is there any technical difficulty that prevents rendering the page on the server and sent to the device while DLLs are loading in the background? And seamlessly switch from server-generated-client-side to client-side without specifically implementing server-side? Such a hybrid solution would solve the main issue of the Blazor.
A lot of complaints are about the initial start speed because of several MBs of runtime DLLs that must be first downloaded while on slow mobile networks.
A large contributor is https://github.com/dotnet/aspnetcore/issues/35302 .
Is there any technical difficulty that prevents rendering the page on the server and sent to the device while DLLs are loading in the background?
@Shalxxx Blazor already supports prerendering from the server.
And seamlessly switch from server-generated-client-side to client-side without specifically implementing server-side? Such a hybrid solution would solve the main issue of the Blazor.
This is something we hope to explore for .NET 8: https://github.com/dotnet/aspnetcore/issues/38128
@danroth27 Doens't solve. The page become unresponsive until the client completely load the big bloated binaries. Prerendering works well when the client load fast enough. Prerendering doesn't work well when system render some content that depends on authentication. Server-side render is good only for search index crowlers, or maybe not even that.
@awillSoftwares You're correct that prerendering only improves the perceived load time of the page. We are discussing how we might in the future enable a combined model where the app starts off with Blazor Server and then transitions to Blazor WebAssembly after the app has been downloaded. Prerendering with authentication is also something we're working on for .NET 7: https://github.com/dotnet/aspnetcore/issues/27592.
@danroth27 Can you also consider what happens if user device/browser does not support WebAssembly. Currently the User-Agent header appears to be the only way to detect device details which is pretty 'wild'. It would be nice to have some property or method such as .IsWebAssemblySupported()
which could test if WebAssembly will actually run on device but without freezing or crashing the application. This would be useful for manual switching between Server/Wasm.
@cirrusone most current browsers support WebAssembly, but you won't be able to detect it reliably on the server side. On the client, it's basically as easy as testing for the existence of the window global variable WebAssembly
. Related: How can I check if a browser supports WebAssembly? (StackOverflow)
There are some instances when WebAssembly itself is supported, but not enabled. The Edge browser does disable WebAssembly support in some cases when using "Enhanced security", or a group policy might disable it for a company. It essentially means checking for the same thing as above.
I have same issue in .net 6 blazor wasm on low-level(desktop) devices and i tried to publish aot mode to help them But in aot mode my app is slower in loadtime,runtime and bigger than normal mode.
@sajjadarashhh Hey Please try to Add Brotli Compressresion into your WASM Project. I am sharing the code Below.
and Some Line of code into Proj. file May be That will Decrease the first load time from your WASM project. Make sure are you using Dotnet 6 SDK.
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<BlazorEnableTimeZoneSupport>false</BlazorEnableTimeZoneSupport>
<BlazorWebAssemblyPreserveCollationData>false</BlazorWebAssemblyPreserveCollationData>
<PublishTrimmed>true</PublishTrimmed>
<BlazorEnableCompression>true</BlazorEnableCompression>
<InvariantGlobalization>true</InvariantGlobalization>
<TrimMode>link</TrimMode>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<!--<RunAOTCompilation>true</RunAOTCompilation>-->
@mandeep-sps
How does this actually work?!!
decode.js
where come from?
@mandeep-sps How does this actually work?!!
decode.js
where come from?
https://docs.microsoft.com/en-us/aspnet/core/blazor/host-and-deploy/webassembly?view=aspnetcore-6.0#compression
@yugabe @jirisykora83 I have added the Brotli Compression into the WASM App. It's working fine at my end. BR applied to all the DLLs files and as well as to Static Files. Please check my Staging Demo Website for Reference purposes. http://182.75.88.147:8126/
@yugabe @jirisykora83 I have added the Brotli Compression into the WASM App. It's working fine at my end. BR applied to all the DLLs files and as well as to Static Files. Please check my Staging Demo Website for Reference purposes. http://182.75.88.147:8126/
I check your site and you are right i load slowly even at second load (where most of the dll should be cached). That dont have to be low-end mobile it is even on my desktop. Hard to say when currently there isnt easy way to profile WASM app.
note: Server location seems to be india (?) and my location is EU so "some" latency is expected.
We are discussing how we might in the future enable a combined model where the app starts off with Blazor Server and then transitions to Blazor WebAssembly after the app has been downloaded.
The switching model in runtime will be great since we take all advantages of both models.
Blazor's performance always slow,never fast 😂
@sgf Slow as hell. And the solution proposed isn't a real solution
i hava an idea
use machine learning/statistics to cherry pick the most usefully API for the runtime libraries. and reduce most useless api. then should be can reduce the Blazor runtime's size.
give develops 2 options: full rutime(10mb)/tiny runtime(1mb)
You can not have your cake and eat it. We have to give up something
@sgf It's a solved problem, as .NET supports trimming assemblies already, and that is not the issue. I'm not sure if you're joking, but machine learning has nothing to do with the issue here either. The problem is that there are certain low end mobile devices that load Blazor slower than they are supposed to and it needs to be investigated why that discrepancy is.
@sgf It's a solved problem, as .NET supports trimming assemblies already, and that is not the issue. I'm not sure if you're joking, but machine learning has nothing to do with the issue here either. The problem is that there are certain low end mobile devices that load Blazor slower than they are supposed to and it needs to be investigated why that discrepancy is.
im not sure,but in my PC(i7 6700). the default created Blazor WebAssembly Project in release mode, the page load need 1.5-2s (Ctrl+F5 every time always need). the broswer is Edge lastest ver.
@sgf So what are you exactly proposing here? Just asking because you're pinging the people on the thread. A 2 second loading time is more than par for the course, given that even JavaScript frameworks need that or more time to load.