aspnetcore icon indicating copy to clipboard operation
aspnetcore copied to clipboard

Improve the load time performance of Blazor WebAssembly apps on low-end mobile devices

Open danroth27 opened this issue 2 years ago • 33 comments

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! 🙏

danroth27 avatar Jun 18 '22 23:06 danroth27

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"

danroth27 avatar Jun 18 '22 23:06 danroth27

Another report of 15s load time on mobile in this issue: https://github.com/dotnet/aspnetcore/issues/41909

danroth27 avatar Jun 21 '22 15:06 danroth27

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?

rogihee avatar Jun 29 '22 05:06 rogihee

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:-

  1. <TargetFramework>net6.0</TargetFramework>
    
  2. <BlazorEnableTimeZoneSupport>false</BlazorEnableTimeZoneSupport>
    
  3. <BlazorWebAssemblyPreserveCollationData>false</BlazorWebAssemblyPreserveCollationData>
    
  4. <PublishTrimmed>true</PublishTrimmed>
    
  5. <BlazorEnableCompression>true</BlazorEnableCompression>
    
  6. <InvariantGlobalization>true</InvariantGlobalization>
    
  7. <TrimMode>link</TrimMode>
    
  8. <!--<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.

image

If I am anything missing Please suggest me.

Thanks

mandeep-sps avatar Jul 01 '22 08:07 mandeep-sps

@mandeep-sps The problem occurs on older devices. Use throttling and do more tests

Alerinos avatar Jul 04 '22 20:07 Alerinos

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: image

So Blazor finishes loading its files at the 400 ms mark, but the first application request is ran a whole second later:

image

image

So is it normal for blazor to take more than a second in starting up? It feels awfully long tbh.

emorell96 avatar Jul 12 '22 14:07 emorell96

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 avatar Aug 04 '22 11:08 ScottKane

@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 avatar Aug 04 '22 15:08 danroth27

@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)

emorell96 avatar Aug 04 '22 15:08 emorell96

@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

ScottKane avatar Aug 04 '22 15:08 ScottKane

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.

Shalxxx avatar Aug 12 '22 15:08 Shalxxx

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 .

charlesroddie avatar Aug 20 '22 21:08 charlesroddie

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 avatar Aug 22 '22 19:08 danroth27

@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 avatar Aug 25 '22 18:08 awillSoftwares

@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 avatar Aug 25 '22 19:08 danroth27

@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 avatar Aug 30 '22 10:08 cirrusone

@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.

yugabe avatar Sep 02 '22 07:09 yugabe

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 avatar Sep 03 '22 21:09 sajjadarashhh

@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 avatar Sep 05 '22 04:09 mandeep-sps

@mandeep-sps How does this actually work?!! decode.js where come from?

GeeSuth avatar Sep 05 '22 07:09 GeeSuth

@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

jirisykora83 avatar Sep 05 '22 07:09 jirisykora83

@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/

mandeep-sps avatar Sep 05 '22 07:09 mandeep-sps

@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.

jirisykora83 avatar Sep 05 '22 08:09 jirisykora83

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.

arthastheking113 avatar Sep 09 '22 07:09 arthastheking113

Blazor's performance always slow,never fast 😂

sgf avatar Sep 13 '22 10:09 sgf

@sgf Slow as hell. And the solution proposed isn't a real solution

awillSoftwares avatar Sep 20 '22 16:09 awillSoftwares

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 avatar Sep 20 '22 17:09 sgf

@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.

yugabe avatar Sep 20 '22 17:09 yugabe

@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 avatar Sep 20 '22 18:09 sgf

@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.

yugabe avatar Sep 20 '22 18:09 yugabe