dotnet / aspnetcore

ASP.NET Core is a cross-platform .NET framework for building modern cloud-based web applications on Windows, Mac, or Linux.
https://asp.net
MIT License
35.37k stars 9.99k forks source link

[Blazor] Auto Render not working properly in .NET 8 and page locks until WebAssembly start #52154

Closed AmBplus closed 9 months ago

AmBplus commented 11 months ago

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.

lockPage
danroth27 commented 11 months ago

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.

@lewing @MackinnonBuck

carlfranklin commented 11 months ago

I’m seeing the same thing

ray440 commented 11 months ago

If you change the Counter title to:

<h1>Counter @(OperatingSystem.IsBrowser() ? "Wasm" : "Server")</h1>

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 @rendermode is?

danroth27 commented 11 months ago

Is there a way to tell what @rendermode is?

Not currently: https://github.com/dotnet/aspnetcore/issues/49401

carlfranklin commented 11 months ago

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 https://github.com/dotnet/aspnetcore/issues/49401

— Reply to this email directly, view it on GitHub https://github.com/dotnet/aspnetcore/issues/52154#issuecomment-1817053655, or unsubscribe https://github.com/notifications/unsubscribe-auth/AALK4DEIYV3XZ563XNJ2ELDYE7BW7AVCNFSM6AAAAAA7P3ZQMOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTQMJXGA2TGNRVGU . You are receiving this because you commented.Message ID: @.***>

mkalinski93 commented 11 months ago

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.

SteveSandersonMS commented 11 months ago

@carlfranklin I’m seeing the same thing

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 because WebAssembly files aren't yet downloaded, there is a small pause (usually< 500ms, but depends on CPU speed) once the WebAssembly files finish downloading. Is that right?

If you change the Counter title to: <h1>Counter @(OperatingSystem.IsBrowser() ? "Wasm" : "Server")</h1> It's kinda neat to watch the change as it happens.

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?

AmBplus commented 11 months ago

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

carlfranklin commented 11 months ago

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 https://github.com/dotnet/aspnetcore/issues/52154#issuecomment-1819395089, or unsubscribe https://github.com/notifications/unsubscribe-auth/AALK4DGFT5QET6HDQOZXO3LYFOAFVAVCNFSM6AAAAAA7P3ZQMOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTQMJZGM4TKMBYHE . You are receiving this because you were mentioned.Message ID: @.***>

ziaulhasanhamim commented 11 months ago

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

SteveSandersonMS commented 11 months ago

In my case the browser first loads webassembly files and then it connects to the server with signalr

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

ziaulhasanhamim commented 11 months ago

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

AmBplus commented 11 months ago

@ziaulhasanhamim , Try Publish And See Still Have Delay

ziaulhasanhamim commented 11 months ago

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

SteveSandersonMS commented 11 months ago

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.

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 localhost? How do you know which part of the delay comes from downloading the WebAssembly files, compared with after the files are downloaded and the WebAssembly runtime is booting up?

ziaulhasanhamim commented 11 months ago

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. My observation on the network tab in slow 3G throttle.

image

I can be totally wrong here. But in general, the Auto mode load time is not appriciatable and mostly same as wasm.

SteveSandersonMS commented 11 months ago

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.

baktay commented 11 months ago

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

achmstein commented 11 months ago

Facing the same issue.

carlfranklin commented 10 months ago

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

<h1>Platform: @(OperatingSystem.IsBrowser() ? "Wasm" : "Server")</h1>

SteveSandersonMS commented 10 months ago

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.

carlfranklin commented 10 months ago

@SteveSandersonMS Done.

SteveSandersonMS commented 10 months ago

Thanks. That does seem pretty convincing. @mkArtakMSFT I think this should be at the top of our priority list.

codeputer commented 10 months ago

I'd this not an issue with the blazor server side unable to to a pre render, and hence, the ux locks up until the client side is ready to address the ux request?

I recently watch a demo of this on the web, and thought I would raise it here (tried to find a reference, but cant find it). This switch on what service is satisfying the request is a tricky spot in this new paradigm of web development

carlfranklin commented 10 months ago

My demo turns off pre-rendering.

On Fri, Dec 1, 2023 at 5:32 PM Richard Reukema @.***> wrote:

I'd this not an issue with the blazor server side unable to to a pre render, and hence, the ux locks up until the client side is ready to address the ux request?

I recently watch a demo of this on the web, and thought I would raise it here (tried to find a reference, but cant find it). This switch on what service is satisfying the request is a tricky spot in this new paradigm of web development

— Reply to this email directly, view it on GitHub https://github.com/dotnet/aspnetcore/issues/52154#issuecomment-1836867457, or unsubscribe https://github.com/notifications/unsubscribe-auth/AALK4DGWMMRBZ45YEJTM6JDYHJLGZAVCNFSM6AAAAAA7P3ZQMOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTQMZWHA3DONBVG4 . You are receiving this because you were mentioned.Message ID: @.***>

danielgreen commented 10 months ago

My demo turns off pre-rendering.

So the UI being locked in your demo isn't due to static content having been rendered?

It's locked even though it should be interactive via SignalR in the interim while wasm starts?

carlfranklin commented 10 months ago

Correct.

On Fri, Dec 1, 2023 at 5:41 PM Daniel Green @.***> wrote:

My demo turns off pre-rendering.

So the UI being locked in your demo isn't due to static content having been rendered?

It's locked even though it should be interactive via SignalR in the interim while wasm starts?

— Reply to this email directly, view it on GitHub https://github.com/dotnet/aspnetcore/issues/52154#issuecomment-1836875475, or unsubscribe https://github.com/notifications/unsubscribe-auth/AALK4DGENZA4HRXX4X7AZ6LYHJMLHAVCNFSM6AAAAAA7P3ZQMOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTQMZWHA3TKNBXGU . You are receiving this because you were mentioned.Message ID: @.***>

codeputer commented 10 months ago

My demo turns off pre-rendering.

So the UI being locked in your demo isn't due to static content having been rendered?

It's locked even though it should be interactive via SignalR in the interim while wasm starts.

Not sure I understand your question - so I'll explain my understanding (happy to be corrected)

I know that one issue with a client I had in Blazor was the behaviour of InitializationAsync being called twice. As I understand it in Blazor 8 - the first time it's called is when it's on the server, and the second time it's called, it's on the client. What he explained was that the first time through the InitializeAsync - you definitely want to be sure that it's not blocked (like waiting for data) because after it exits that method does the server release the pre-rendered HTML data down to the client. At this point the client works to present the HTML on the screen (typically this is showing the "Loading..." eye candy stuff). Once it's done that (this is without a socket) the WASM prep and download starts to happen. Interaction with the server with Blazor Socket, can only start after the JS file is downloaded, as its an outbound connection with the server that starts the websocket connection. Delay the pre-render, and you delay the socket being established as well, and the whole thing locks up until WASM is fully established (something that should be avoided in my thinking). My preference is to leave everything on the server, unless the application requires off-line capabilities, or even heavy in terms of graphics (like casino application for example).

david-at-solve commented 10 months ago

I could also reproduce it on my machine. The problem is not the WASM startup time but that the blazor-server-websocket-connection is not set up because it has to wait for the other resources to be fetched (probably due to a limitation in max concurrent browser fetches?).

The "initial state" is from server-side prerendering. You can see on the button clicks that interactivity is not working.

https://github.com/dotnet/aspnetcore/assets/139991064/5b6cde74-8c58-400c-b12d-8b3558831e64

I used the platform detection code from Carl Franklin. Same behavior when publishing the app :/

arthastheking113 commented 10 months ago

I can reproduce this issue as I mentioned in #52597 with some suggestions.

MackinnonBuck commented 10 months ago

Hi all - we really appreciate all the community engagement on this issue. It's clear to us that there are improvements we can make to the Auto render mode to better support certain scenarios, and we're working quickly to ensure that we make the right improvements.

The nature of this feature makes it behave differently on different types of devices, connections, and apps. That's why it's valuable for us to get feedback about whether the improvements we make are going to address the concerns being expressed here.

To provide some insight, the primary issues people seem to be experiencing are:

  1. Downloading WebAssembly resources in parallel means that the leftover bandwidth for other network activity (like initializing a websocket connection or fetching a new page) may be too small to be effective. This results in cases like:
    • The Blazor Server circuit appearing to "wait" for WebAssembly resource downloads to complete
    • Page navigations or link clicks "waiting" until WebAssembly resources are downloaded
  2. Especially when debugging locally, the page may momentarily "lock up" after WebAssembly resources have been downloaded. For a brief period, animations stop playing, text boxes stop receiving input, etc. This happens because when WebAssembly resources are already cached or get downloaded quickly, then the Auto render mode may decide to use WebAssembly for interactivity. Blazor's WebAssembly interactivity startup is largely synchronous, and since debug builds are slower and have more work to do (e.g., initialize hot reload functionality), then this blocking period when debugging can appear significant (up to a second or so, from my experience). This issue shouldn't affect published apps, but it's still a continuous effort of ours to make improvements to Blazor WebAssembly startup time.

Call to action

I've locally made some small adjustments to the Auto render mode and seen significant improvement, particularly as it relates to issue [1] described above. We would really appreciate it if you could try out these changes to see if they improve your own apps. The most notable changes is a fix that allows the downloading of WebAssembly resources to be throttled to reduce their impact on other network activity.

To test these changes, download the files from this gist, and place them in your wwwroot folder. This following example assumes these files are placed in the wwwroot/js folder, so you'll have to adjust the following code accordingly if you make a different choice.

In your App.razor file, replace the script element referencing blazor.web.js with the following:

<script src="js/blazor.web.patched.js" autostart="false"></script>
<script>
    Blazor.start({
        webAssembly: {
            loadBootResource: function (type, name, defaultUri, integrity) {
                if (type === 'dotnetjs' && name === 'dotnet.js') {
                    return 'js/dotnet.patched.js';
                }
                return `_framework/${name}`;
            },
            configureRuntime: (builder) => {
                builder.withConfig({
                    maxParallelDownloads: 1, // Adjust this to change the WebAssembly resource throttling amount
                });
            },
        },
    });
</script>

We may also experiment with other changes, like delaying the start of WebAssembly resource downloads until the circuit connects. This might improve the initial time to interactivity, even if the websocket connection quality continues to be slightly affected by the downloading of WebAssembly resources in the background. Until then, we'd love to hear your feedback!

carlfranklin commented 10 months ago

I will check it out, thanks!

Is it possible to make the WASM download happen on a lower-priority thread? If we have a circuit, what's the rush to get to WASM?

In my DevIntersection talk today someone asked what happens to the state? Do my variables re-initialize once WASM is loaded? If that's the case, would it work to have a new virtual lifecycle method? Do we just look at OperatingSystem.IsBrowser() in OnAfterRender, assuming that OnAfterRender is called when WASM is ready?

Thanks again for tackling this.

Carl

On Wed, Dec 6, 2023 at 2:12 PM Mackinnon Buck @.***> wrote:

Hi all - we really appreciate all the community engagement on this issue. It's clear to us that there are improvements we can make to the Auto render mode to better support certain scenarios, and we're working quickly to ensure that we make the right improvements.

The nature of this feature makes it behave differently on different types of devices, connections, and apps. That's why it's valuable for us to get feedback about whether the improvements we make are going to address the concerns being expressed here.

To provide some insight, the primary issues people seem to be experiencing are:

  1. Downloading WebAssembly resources in parallel means that the leftover bandwidth for other network activity (like initializing a websocket connection or fetching a new page) may be too small to be effective. This results in cases like:
    • The Blazor Server circuit appearing to "wait" for WebAssembly resource downloads to complete
    • Page navigations or link clicks "waiting" until WebAssembly resources are downloaded
  2. Especially when debugging locally, the page may momentarily "lock up" after WebAssembly resources have been downloaded. For a brief period, animations stop playing, text boxes stop receiving input, etc. This happens because when WebAssembly resources are already cached or get downloaded quickly, then the Auto render mode may decide to use WebAssembly for interactivity. Blazor's WebAssembly interactivity startup is largely synchronous, and since debug builds are slower and have more work to do (e.g., initialize hot reload functionality), then this blocking period when debugging can appear significant (up to a second or so, from my experience). This issue shouldn't affect published apps, but it's still a continuous effort of ours to make improvements to Blazor WebAssembly startup time.

Call to action

I've locally made some small adjustments to the Auto render mode and seen significant improvement, particularly as it relates to issue [1] described above. We would really appreciate it if you could try out these changes to see if they improve your own apps. The most notable changes is a fix that allows the downloading of WebAssembly resources to be throttled to reduce their impact on other network activity.

To test these changes, download the files from this gist https://gist.github.com/MackinnonBuck/460b0493eb8dda3f570900cfb3bb1c62, and place them in your wwwroot folder. This following example assumes these files are placed in the wwwroot/js folder, so you'll have to adjust the following code accordingly if you make a different choice.

In your App.razor file, replace the script element referencing blazor.web.js with the following:

We may also experiment with other changes, like delaying the start of WebAssembly resource downloads until the circuit connects. This might improve the initial time to interactivity, even if the websocket connection quality continues to be slightly affected by the downloading of WebAssembly resources in the background. Until then, we'd love to hear your feedback!

— Reply to this email directly, view it on GitHub https://github.com/dotnet/aspnetcore/issues/52154#issuecomment-1843535849, or unsubscribe https://github.com/notifications/unsubscribe-auth/AALK4DG5T7BFNYAKAG2XAVDYIC7SFAVCNFSM6AAAAAA7P3ZQMOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTQNBTGUZTKOBUHE . You are receiving this because you were mentioned.Message ID: @.***>

carlfranklin commented 10 months ago

I published a new demo to Azure using .NET 8 self-contained and turned on WebSockets.

https://blazor8test.azurewebsites.net/counter

I set maxParallelDownloads to 2.

The result is that it still doesn't let me click before WASM files are downloaded.

I really like the idea of starting the download AFTER the circuit is connected, if possible on a lower priority thread.

Carl

On Wed, Dec 6, 2023 at 2:55 PM Carl Franklin @.***> wrote:

I will check it out, thanks!

Is it possible to make the WASM download happen on a lower-priority thread? If we have a circuit, what's the rush to get to WASM?

In my DevIntersection talk today someone asked what happens to the state? Do my variables re-initialize once WASM is loaded? If that's the case, would it work to have a new virtual lifecycle method? Do we just look at OperatingSystem.IsBrowser() in OnAfterRender, assuming that OnAfterRender is called when WASM is ready?

Thanks again for tackling this.

Carl

On Wed, Dec 6, 2023 at 2:12 PM Mackinnon Buck @.***> wrote:

Hi all - we really appreciate all the community engagement on this issue. It's clear to us that there are improvements we can make to the Auto render mode to better support certain scenarios, and we're working quickly to ensure that we make the right improvements.

The nature of this feature makes it behave differently on different types of devices, connections, and apps. That's why it's valuable for us to get feedback about whether the improvements we make are going to address the concerns being expressed here.

To provide some insight, the primary issues people seem to be experiencing are:

  1. Downloading WebAssembly resources in parallel means that the leftover bandwidth for other network activity (like initializing a websocket connection or fetching a new page) may be too small to be effective. This results in cases like:
    • The Blazor Server circuit appearing to "wait" for WebAssembly resource downloads to complete
    • Page navigations or link clicks "waiting" until WebAssembly resources are downloaded
  2. Especially when debugging locally, the page may momentarily "lock up" after WebAssembly resources have been downloaded. For a brief period, animations stop playing, text boxes stop receiving input, etc. This happens because when WebAssembly resources are already cached or get downloaded quickly, then the Auto render mode may decide to use WebAssembly for interactivity. Blazor's WebAssembly interactivity startup is largely synchronous, and since debug builds are slower and have more work to do (e.g., initialize hot reload functionality), then this blocking period when debugging can appear significant (up to a second or so, from my experience). This issue shouldn't affect published apps, but it's still a continuous effort of ours to make improvements to Blazor WebAssembly startup time.

Call to action

I've locally made some small adjustments to the Auto render mode and seen significant improvement, particularly as it relates to issue [1] described above. We would really appreciate it if you could try out these changes to see if they improve your own apps. The most notable changes is a fix that allows the downloading of WebAssembly resources to be throttled to reduce their impact on other network activity.

To test these changes, download the files from this gist https://gist.github.com/MackinnonBuck/460b0493eb8dda3f570900cfb3bb1c62, and place them in your wwwroot folder. This following example assumes these files are placed in the wwwroot/js folder, so you'll have to adjust the following code accordingly if you make a different choice.

In your App.razor file, replace the script element referencing blazor.web.js with the following:

We may also experiment with other changes, like delaying the start of WebAssembly resource downloads until the circuit connects. This might improve the initial time to interactivity, even if the websocket connection quality continues to be slightly affected by the downloading of WebAssembly resources in the background. Until then, we'd love to hear your feedback!

— Reply to this email directly, view it on GitHub https://github.com/dotnet/aspnetcore/issues/52154#issuecomment-1843535849, or unsubscribe https://github.com/notifications/unsubscribe-auth/AALK4DG5T7BFNYAKAG2XAVDYIC7SFAVCNFSM6AAAAAA7P3ZQMOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTQNBTGUZTKOBUHE . You are receiving this because you were mentioned.Message ID: @.***>

SteveSandersonMS commented 10 months ago

The result is that it still doesn't let me click before WASM files are downloaded.

That's strange. I just tried your new site on a throttled connection and it did work this time - I was able to use the counter immediately, even though I could see the webassembly resources were still downloading for a long time in the background.

carlfranklin commented 10 months ago

Maybe I don't understand what OperatingSystem.IsBrowser() means when it returns true. If I press F5 to refresh, it only returns false for a second, and then switches to WASM. During that one second, the button is not responsive.

[image: image.png]

On Wed, Dec 6, 2023 at 3:19 PM Steve Sanderson @.***> wrote:

The result is that it still doesn't let me click before WASM files are downloaded.

That's strange. I just tried your new site on a throttled connection and it did work this time - I was able to use the counter immediately, even though I could see the webassembly resources were still downloading for a long time in the background.

— Reply to this email directly, view it on GitHub https://github.com/dotnet/aspnetcore/issues/52154#issuecomment-1843627795, or unsubscribe https://github.com/notifications/unsubscribe-auth/AALK4DFQQD32DBMQCXUCALDYIDHO5AVCNFSM6AAAAAA7P3ZQMOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTQNBTGYZDONZZGU . You are receiving this because you were mentioned.Message ID: @.***>

carlfranklin commented 10 months ago

I throttled the connection. It took longer to switch to WASM, but the button was still unresponsive in Server mode.. What's more, I see no websockets.

[image: image.png]

On Wed, Dec 6, 2023 at 3:37 PM Carl Franklin @.***> wrote:

Maybe I don't understand what OperatingSystem.IsBrowser() means when it returns true. If I press F5 to refresh, it only returns false for a second, and then switches to WASM. During that one second, the button is not responsive.

[image: image.png]

On Wed, Dec 6, 2023 at 3:19 PM Steve Sanderson @.***> wrote:

The result is that it still doesn't let me click before WASM files are downloaded.

That's strange. I just tried your new site on a throttled connection and it did work this time - I was able to use the counter immediately, even though I could see the webassembly resources were still downloading for a long time in the background.

— Reply to this email directly, view it on GitHub https://github.com/dotnet/aspnetcore/issues/52154#issuecomment-1843627795, or unsubscribe https://github.com/notifications/unsubscribe-auth/AALK4DFQQD32DBMQCXUCALDYIDHO5AVCNFSM6AAAAAA7P3ZQMOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTQNBTGYZDONZZGU . You are receiving this because you were mentioned.Message ID: @.***>

MackinnonBuck commented 10 months ago

In my DevIntersection talk today someone asked what happens to the state? Do my variables re-initialize once WASM is loaded? If that's the case, would it work to have a new virtual lifecycle method? Do we just look at OperatingSystem.IsBrowser() in OnAfterRender, assuming that OnAfterRender is called when WASM is ready?

The Auto render mode doesn't dynamically change the render mode of components that have already become interactive. It makes an initial decision based on whether WebAssembly resources are cached. If they are, then WebAssembly interactivity gets used. If they aren't, then Server interactivity is used, but the download of WebAssembly resources starts so that on the next visit to the site (or the next refresh), WebAssembly gets used.

Allowing components to dynamically switch from Server interactivity to WebAssembly interactivity poses some interesting challenges, but it's something worth considering for investigation in .NET 9.

Side note: when testing the Auto mode feature, it might help to distinguish between the "statically rendered but not yet interactive" case from the "server interactive" case. Here's the counter component I've been using:

<p role="status">Current count: @currentCount</p>

<p>Render mode: @renderMode</p>

<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>

@code {
    private int currentCount = 0;
    private string renderMode = "SSR";

    private void IncrementCount()
    {
        currentCount++;
    }

    protected override void OnAfterRender(bool firstRender)
    {
        if (firstRender)
        {
            renderMode = OperatingSystem.IsBrowser() ? "WebAssembly" : "Server";
            StateHasChanged();
        }
    }
}
arthastheking113 commented 10 months ago

@MackinnonBuck I tested it out. I see we can control how many maxParallelDownloads as we want. Navigation is using Server Side Prerendering which is very good for SEO. The only thing I don't see is the Signal R connection, there is no Signal R to start connecting to activate Interactive Server mode.

It would be great if we can start first by connecting Signal R and have to wait for Signal R connected Successfully then start downloading .wasm files.

david-at-solve commented 10 months ago

Hello @MackinnonBuck, I tried out your changes and it works as expected :)

For the following video I disabled SSR for the Counter component and used maxParallelDownloads: 3.

https://github.com/dotnet/aspnetcore/assets/139991064/4ee082e8-41bb-40e3-89a5-b911d0c3d83e

As you can see the Counter component is usable and it's also possible to navigate to other pages. The WASM runtime then needs some time for the first startup, but the second startup is a lot faster. Auto mode as expected :)

The Idea with "waiting for Blazor Server connection" is good but probably not the only thing required. Because users also navigate to other pages those HTTP calls (including images, further styles, ...) also need to have the chance to get executed early, so I think a combination of "late wasm download + maxParallelDownloads" would be great :)

And I want to thank you all for your great work in inventing and developing Blazor 🎉 👏 👏 👏

ihorlazarenko commented 10 months ago

For me, interactive Server side rendering is never used in Auto mode. I disabled prerendering, switched to "slow 3G" mode in networking in browser and had been observing 22 sec empty counter control before wasm libs were downloaded. Auto mode behaves like webassembly mode, there are no differences for me.

smcleod77 commented 10 months ago

Hello @MackinnonBuck, I tried out your changes and it works as expected :)

For the following video I disabled SSR for the Counter component and used maxParallelDownloads: 3.

blazor-interactive-auto-with-hotfix.mp4 As you can see the Counter component is usable and it's also possible to navigate to other pages. The WASM runtime then needs some time for the first startup, but the second startup is a lot faster. Auto mode as expected :)

The Idea with "waiting for Blazor Server connection" is good but probably not the only thing required. Because users also navigate to other pages those HTTP calls (including images, further styles, ...) also need to have the chance to get executed early, so I think a combination of "late wasm download + maxParallelDownloads" would be great :)

And I want to thank you all for your great work in inventing and developing Blazor 🎉 👏 👏 👏

this functionality looks like it working as advertised... when will this be live in .NET 8, need it to proceed with migrating to a BlazorWebApp InteractiveAuto mode? Anyone know or have a guesstimated timeline? :)

mandeep-sps commented 10 months ago

Hi Team,

I am facing a Page title Issue in the Blazor Dotnet 8 with Auto Mode and Prerender:False I am using these lines of codes:-

`@page "/sfgrid-Grid" @attribute [StreamRendering] @rendermode @(new InteractiveAutoRenderMode(prerender:false)) @ @rendermode InteractiveAuto @

Employee Listing` Please help me on this part Thanks
CreamyMiracle commented 10 months ago

I was banging my head against the wall and almost gave up trying InteractiveAuto rendering since it didn't make any sense to wait all WASM files to be downloaded before the websocket circuit was healthy and the InteractiveServer rendering kicked in.

Many thanks to @MackinnonBuck to provide a workaround for this problem!

Hope this fix will be included in Blazor Web App templates soon!

smcleod77 commented 10 months ago

I was banging my head against the wall and almost gave up trying InteractiveAuto rendering since it didn't make any sense to wait all WASM files to be downloaded before the websocket circuit was healthy and the InteractiveServer rendering kicked in.

Many thanks to @MackinnonBuck to provide a workaround for this problem!

Hope this fix will be included in Blazor Web App templates soon!

agreed, i was banging my head as well, didn't see a point to using InteractiveAuto until I realized (mainly from this post) that it was not working correctly... I'm sure there are many many others banging their heads too wondering why it is not working as you'd expect...

any guess on a timeline as to when this will be released? or will it not be?

MackinnonBuck commented 10 months ago

any guess on a timeline as to when this will be released? or will it not be?

We're working on addressing the issue with the hope that the fix will be low risk enough to patch it in an upcoming servicing release.

fdonnet commented 10 months ago

same here... I was questioning myself about the purpose because it always switchs to wasm at the first load and it take sometimes to load. In InteractiveServer it's quick. But ok, it's not the expected behavior... we need to have the speed of the InteractiveServer first load and the WASM loading in background for the next uses of the component or for sure, automode is not useful.

bxjg1987 commented 10 months ago

I was banging my head against the wall and almost gave up trying InteractiveAuto rendering since it didn't make any sense to wait all WASM files to be downloaded before the websocket circuit was healthy and the InteractiveServer rendering kicked in. Many thanks to @MackinnonBuck to provide a workaround for this problem! Hope this fix will be included in Blazor Web App templates soon!

agreed, i was banging my head as well, didn't see a point to using InteractiveAuto until I realized (mainly from this post) that it was not working correctly... I'm sure there are many many others banging their heads too wondering why it is not working as you'd expect...

any guess on a timeline as to when this will be released? or will it not be?

Yes, this is completely different from the auto mode in the advertisement. I have already wasted a week on this matter, and fortunately, the blazer team is actively addressing this issue.

mikes-gh commented 9 months ago

My experience is the same.

Open private window to simulate first visit. Open Browser tools to monitor responses. Click on Counter. Not interactive for about 5-7 seconds in my environment. The Web socket is only connected after all wasm resources have been downloaded.

image

mikes-gh commented 9 months ago

@MackinnonBuck When is the BSS websocket meant to cleanup once the page is using wasm? I am thinking of server resources here.

mikes-gh commented 9 months ago

I tested @MackinnonBuck fix here https://github.com/dotnet/aspnetcore/issues/52154#issuecomment-1843535849 and it is a significant improvement. Thanks for looking into it. Ultimately rescheduling/delaying the wasm startup procedure would be preferable than turning off parallel downloads but it does work a lot faster.