-
Notifications
You must be signed in to change notification settings - Fork 10.1k
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
[Blazor] Auto Render not working properly in .NET 8 and page locks until WebAssembly start #52154
Comments
The delay is most likely due to starting up the .NET WebAssembly runtime, not the download. I believe the issue is we don't currently have a way to download the .NET WebAssembly runtime without also starting it, so this delay happens even on the first visit when using interactive server rendering. But even if we could avoid that delay on the first visit, on subsequent visits you'd still see the delay as the runtime starts up even though the runtime has been cached. |
I’m seeing the same thing |
If you change the Counter title to:
It's kinda neat to watch the change as it happens. The delay is expected but much longer than expected leading to a stalled UX for antsy users. Is there a way to tell what |
Not currently: #49401 |
Can we hook afterWebAssemblyStarted in JavaScript to determine when WASM is
loaded ?
…On Fri, Nov 17, 2023 at 3:24 PM Daniel Roth ***@***.***> wrote:
Is there a way to tell what @rendermode is?
Not currently: #49401 <#49401>
—
Reply to this email directly, view it on GitHub
<#52154 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AALK4DEIYV3XZ563XNJ2ELDYE7BW7AVCNFSM6AAAAAA7P3ZQMOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTQMJXGA2TGNRVGU>
.
You are receiving this because you commented.Message ID:
***@***.***>
|
I found out that OnAfterRender actually can be an indicator that the framework and dependencies has been loaded. I think I'm going to have a root level component that will display a waiting indicator or something. My problem is that my clients will have a fast initial response from the server, but the overall hydration is taking a long time (especially on mobile end with slow connectivity) In the end, my clients would be more confused when there's no interactivity yet established. My observation is that OnAfterRender gets executed when the framework has been loaded fully. Maybe we can get used to it. |
Can you clarify what same thing you are seeing? The original report suggested that the UI is locked while downloading WebAssembly resources, but as far as we understand that is not the case. If you mean that the UI is locked while the WebAssembly runtime starts (not while downloading, but after downloading), this is true and always has been since the beginning of Blazor WebAssembly. Over the years we've made it faster - it took about 1 second to start on the first version, and is down to about 350ms on recent hardware. Of course it could take longer on a low-end mobile device. Update: I think I get what you mean now, which is that on the first visit for a given user, when it's using Server interactivity
The switchover you'll be seeing here is between prerendered content (which will display "Server") and then live interactive content (which will display "Wasm" if the wasm resources are already downloaded and cached). What sort of delay are you seeing that is much longer than expected? |
It seems this problem only happens in debug mode. What I mean is that it's more noticeable, not that there is no locking at all in other modes. |
Thanks!
…On Mon, Nov 20, 2023 at 11:27 AM Amir ***@***.***> wrote:
@SteveSandersonMS <https://github.com/SteveSandersonMS> (usually< 500ms,
but depends on CPU speed)
It seems this problem only happens in debug mode. What I mean is that it's
more noticeable, not that there is no locking at all in other modes.
In debug mode with Visual Studio it takes around 6 seconds , with dotnet
run it takes less than 1 sec or half sec, and in release you almost don't
feel your page is locked.
It seems like we don't have any issues in production mode.
—
Reply to this email directly, view it on GitHub
<#52154 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AALK4DGFT5QET6HDQOZXO3LYFOAFVAVCNFSM6AAAAAA7P3ZQMOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTQMJZGM4TKMBYHE>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
@SteveSandersonMS I am facing the same issue. In auto interactivity mode it is supposed to connect to the server with signalr instantly. But it doesn't do that rather it waits for the wasm runtime to be loaded and then connects to the server. It destroys the whole purpose of auto interactivity. The app doesn't become interactive before wasm runtime loads unlike server mode which starts instantaneously. In my case the browser first loads webassembly files and then it connects to the server with signalr. Shouldn't it first make a signalr connection and then load the files? In my network tab, I can clearly see that wasm files are downloaded before websocket connection. |
@ziaulhasanhamim When you use the word "loads" here, do you mean "downloads" (as in the WebAssembly files are not already cached, and you are waiting for them to be transferred over the network), or do you mean it in the sense of "starts" (as in, the WebAssembly files are already downloaded, but it takes some nonzero time to start the .NET runtime under WebAssembly, most likely ~0.5s assuming you are not debugging). |
@SteveSandersonMS I meant that it is not cached. When wasm runtime is not cached it first downloads the wasm files then connects to server through websockets. But if it has to download the wasm runtime first then what is the benefit of auto interactivity. |
@ziaulhasanhamim , Try Publish And See Still Have Delay |
Yeah in publish delay is less. But fundamentally it's a problem because what is benefit of auto interactivity if wasm runtime needs to be downloaded first(runtime is not cached already) before websocket connection |
If that's true it would be very surprising and a definite major bug we'd hurry to patch. However I don't think we've ever observed this happening, so it's also possible that something else is going on. Can you clarify how you know this is what's happening? Are you talking about when running on |
Yes, I'm facing it on localhost. The network tab shows that first, it is downloading the whole wasm runtime and then connecting the websocket. Moreover, in the console tab Blazor websocket connection message and runtime loaded message are emitted together, and after it the page becomes interactive. Also In auto interactive mode, first load time is as bad as webassembly load time whereas in server mode it loads instantly. I can be totally wrong here. But in general, the Auto mode load time is not appriciatable and mostly same as wasm. |
Thanks @ziaulhasanhamim for the clarification. This is helpful. It's possible that this problem only surfaces in the artificial localhost+throttling case rather than in real deployments. We're investigating to confirm, and will certainly look to improve this quickly either way. |
I used the sample counter-weather code as is. I switched to counter page and clicked Click Me button immediately. Nothing happened for couple of clicks until it worked (I am not using a super fast computer). Then, I changed counter page rendermode to InteractiveServer and refreshed the page. It worked immediately. My first immediate click worked. InteractiveAuto does not seem to render from server first time (at least not as good as InteractiveServer rendermode) when compared. My workaround was to create the counter page as @rendermode InteractiveServer and put the Counter code into a counter component named CounterComponent at wasm pages folder. Then used: <CounterComponent @rendermode="RenderMode.InteractiveAuto"> |
Facing the same issue. |
@SteveSandersonMS I published a test app to Azure at https://blazorautotest.azurewebsites.net/ It does load fast, but try to click the button before it reads "Platform: Wasm" I'm using this technique:
|
Thanks @carlfranklin. Yes that is helpful and probably does confirm the issue. One minor remaining detail though: I see your deployment is not configured to enable WebSockets, so it's falling back on long polling. Could you update it so it does enable WebSockets? Then assuming the same issue still repros, that would be a complete smoking gun. |
@SteveSandersonMS Done. |
Thanks. That does seem pretty convincing. @mkArtakMSFT I think this should be at the top of our priority list. |
Looks like it only got merged 10 hours ago and is labelled |
That label is misleading, that PR is a mechanical one that brings in any internal fixes from the previous month. All of the commits in that PR, except for the last 2, were internal commits that were included with 8.0.2. If you browse the commit history from the v8.0.2 tag (below), you can see that the render mode fix was included in 8.0.2. https://github.com/dotnet/aspnetcore/commits/v8.0.2/ @MackinnonBuck any thoughts on why customers might not be seeing the new behavior with the change? |
The fix was included in 8.0.2. I confirmed this by installing the SDK on a fresh machine and testing a Blazor Web App with "Auto" interactivity by creating a new project from the project template. All that should be required for existing projects is updating My verification steps were the following:
A few notes/caveats:
For those that see issues not described by the above, could you describe what problem you're seeing? Thanks! |
To expand on this, if someone can point out to a difference in behavior between 8.0.2 and the fix that I linked in a previous comment, that would potentially point to a bug. Thanks! |
@MackinnonBuck For me I made sure all my references were Although I thought previously without the fix the websocket came after all the libraries for the app had downloaded. It seems now only the main dotnet wasm runtime comes before the websocket so maybe the delay is something else locally like debugger startup. I probably need to setup both senarios alonside each other to be sure |
A small update. My experience of that delay and switchover to wasm rather than staying in interactive server has been resolved. I thoughtlessly deleted the original client project instead of the one I added and didn't observe that there was an extra package reference. <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="8.0.2" PrivateAssets="all" />
As soon as I realized that this was the only difference I could find between a fresh template and my project I removed it, cleaned, rebuilt, ran without debugging, and there it was. The behavior was working correctly as you had described. Apologies for reopening this can of worms over an error on my part. |
Auto-mode now works as expected, thank you! |
@ashishsinha24 Can you share more details about the issue you're still seeing? |
I am still seeing that the app locks until the wasm is downloaded. I am seeing it in debug and release versions. I am using Radzen controls. Maybe the problem is specific to this. I haven't had the time to fully test it. |
If the app is locking up, it's probably the WebAssembly runtime starting, not being downloaded. The WebAssembly runtime starts synchronously, which is why the webpage becomes temporarily non-interactive. Does the same thing happen when using an |
TIA |
It's not expected, but I don't think this is what's happening in the screenshot you shared. If you're pointing out that
The fix only alters |
I tested a new application created as Global InteractiveAuto and everything works as expected. I can switch between pages and Counter page is interactive while wasm files are loaded. @ashishsinha24 I have no experience with Radzen components, but I have some with DevExpress. Simple application with one DxGrid downloads A LOT of files and it is huge. Here is an interesting blog post: Maybe you see the problem described by @MackinnonBuck (WebAssembly startup.) On a fast computer I have to wait 1 s. before WebAssembly app with DevExpress components will be interactive. On iPhone 6s and laptop with Intel Core i7-6500U processor I have to wait about 4 s. It is possible that app with Radzen component also needs a few seconds to start on your hardware. |
I'm a bit lost on the order of things. I hadn't considered that the WebAssembly runtime starting could block the Blazor Server interactivity. So if the app downloads quite quickly then the WebAssembly runtime starting can still block the Blazor Server interactivity giving the same feel that the app is not responding even though the websocket is open? |
I should have been clearer - the WebAssembly runtime (as in the code from the |
Thanks for the fix, @MackinnonBuck. I updated my SDK to 8.0.2 and tried on a new project and the issue looks fixed. However, I see that all the wasm files are downloaded serially (see image below). Is there a way to make this parallel (or, say 10 degrees of parallelism), while still having the websocket connection be established before the wasm is downloaded? |
@saintarian you cannot download 10 files concurrently because your application will be unusable. Maybe it is not a problem on high speed fiber Internet connection but try to download a few files concurrently using cellular network and check latency with ping command. |
Regarding the content here, the official document does not seem to provide a detailed explanation. Would you like to supplement this document |
# Auto render mode improvements Backport of dotnet/aspnetcore#53159 Improves the Auto render mode so that components are more responsive and have a decreased initial time to interactivity when WebAssembly resources are not already cached. ## Description One of the goals of the Auto render mode was to allow apps to become interactive as quickly as possible via Server interactivity, while WebAssembly bits were downloaded in the background for use on future visits to the site. However, since WebAssembly resources were being downloaded with maximal parallelism, the quality of the websocket connection required for Server interactivity was negatively impacted, often to the extent that the websocket wouldn't connect until WebAssembly resources had finished downloading completely, largely defeating the purpose of the Auto render mode. This PR makes the following improvements: * Removes a problematic timeout on loading the WebAssembly boot config. This fixes a problem where Server interactivity was always being used when the boot config took too long to load. * Introduces a limit to the maximum parallel WebAssembly resource downloads when an Auto component initiates the startup of the WebAssembly runtime. This limit is set to 1 and overrides any user-specified limit. * Fixes an issue where the circuit sometimes remains open even if WebAssembly gets selected for Auto interactivity. I provided a preview of these changes in dotnet/aspnetcore#52154 (comment) so that customers could try them out, and the feedback so far has been very positive. Fixes dotnet/aspnetcore#52154 ## Customer Impact A significant number of customers reported being affected by this problem in issues like dotnet/aspnetcore#52154. I supplied customers with a preview of the fix that they could patch it into their app, and many indicated that their problems were resolved by the fix. The Auto render mode was one of the key features released in .NET 8, so it's important that it works in the way we've been advertising. ## Regression? - [ ] Yes - [X] No ## Risk - [ ] High - [ ] Medium - [X] Low The core Auto render mode functionality is unaffected by this change - we added small tweaks to adjust the throttling amount and remove a problematic timeout. Additional tests were added to verify the changes in behavior, and we've been testing these changes manually to ensure they work well in real-world scenarios (various device types and connection qualities). ## Verification - [X] Manual (required) - [X] Automated ## Packaging changes reviewed? - [ ] Yes - [ ] No - [X] N/A
@bcookew If the page initially loads in server mode then it will be trying to resolve the injected dependencies from the server side service provider. The dependencies will need to be present there, if they're not that could explain the problems. |
Good offer. That was, in truth, where I started my day. I had a look at the MS Docs related to render modes here. And followed their advice to set prerender to false. This did indeed clear the DI issue but left me with this odd behavior where the page never loads unless I refresh a couple of times. Open to further thoughts / discussion on this for sure! |
@bcookew It still sounds like a DI issue. Setting prerender to false will still mean it tries to load in server (SignalR) mode initially. Then when you refresh, if the wasm resources have been downloaded by that point then after refreshing it will switch to wasm mode. |
@danielgreen |
I stumbled upon a similar problem. A browser which doesn't have WASM or WASM is disabled alltogether. I tested with Firefox setting javascript.options.wasm to false. I'd expect it to still work using server-side rendering. Instead, it seems like it crashes and no interactivity works. |
Is there an existing issue for this?
Describe the bug
I updated Visual Studio to the latest version 17.8.0 and created a Blazor app using Auto render mode With Dotnet 8. When I run the application and navigate to the Counter tab, the whole page locks up until the WebAssembly Start. I can't do anything or switch to another tab until the download Finished And WebAssembly Start, even though it happens quickly locally. This could cause problems in production where the download may take longer. It also goes against the purpose of Auto render mode.
Expected Behavior
With auto render mode, the page should initially use server-side rendering. Once WebAssembly finishes downloading And Start, it can switch over seamlessly without locking up the page.
Steps To Reproduce
No response
Exceptions (if any)
No response
.NET Version
NET 8 , Windows 10-64
Anything else?
As you can see, the page is locked and prevents navigating to another tab.
The text was updated successfully, but these errors were encountered: