Skip to content
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 Pre-rendering and PersistingComponentStateSubscription not working correctly with dotnet 9? #34229

Open
MattCost opened this issue Nov 27, 2024 · 19 comments · May be fixed by #34445
Open

Comments

@MattCost
Copy link

MattCost commented Nov 27, 2024

Description

Steps to reproduce

  1. Make a new template dotnet new blazor
  2. add @rendermode InteractiveServer to the weather page
  3. Start the app
  4. Go to /weather
    1 Observe the double rendering in action.
  5. Add in code from https://learn.microsoft.com/en-us/aspnet/core/blazor/components/prerender?view=aspnetcore-9.0 to use PersistingComponentStateSubscription to save data
  6. Restart the app
  7. Navigate back and forth using the navigation links on the left hand side. (between home and weather and counter). Most times the double rendering still occurs on the weather page, sometimes it does not.
  8. Navigate to /home via the link on the left.
  9. Manually type in /weather into the url
  10. Double rendering never occurs when manually typing in the url

Questions

Why does the persisting only work sometimes?

The page has the following note If the app adopts interactive routing and the page is reached via an internal navigation, prerendering doesn't occur. Therefore, you must perform a full page reload for the PrerenderedCounter2 component to see the following output.

This doesn't make sense. Using internal navigation, prerendering is still occuring, and persisting is NOT working to stop it. Is this note out of date?

Are there changes in dotnet 9 to how the PersistingComponentStateSubscription works? or how pre-rendering works?

Not sure if this needs to be a bug report in another repo, or if this is just a documentation issue.

Page URL

https://learn.microsoft.com/en-us/aspnet/core/blazor/components/prerender?view=aspnetcore-9.0

Content source URL

https://github.com/dotnet/AspNetCore.Docs/blob/main/aspnetcore/blazor/components/prerender.md

Document ID

ffdc8df3-55a8-b757-d4e6-38c104916002

Article author

@guardrex

Related Issues

Copy link
Contributor

🍂🎃🏮 Autumn Skies and Pumpkin Pies! 🥧☕🍂

Stand by! A green dinosaur 🦖 will arrive shortly to assist.

@MattCost
Copy link
Author

Sample repo https://github.com/MattCost/blazorTest

@guardrex
Copy link
Collaborator

Hello @MattCost ...

I don't think the NOTE is incorrect; however, this behavior might be a bit more complex than what the NOTE states and require more explanation.

We're right on the doorstep of leaving for the 🦃 holiday, so I won't be able to get a product unit member to look at this today. I'll ping one of them next week to come on and take a look to see if we can improve the coverage.

@guardrex guardrex moved this from Triage to P0/P1 - High Priority in Blazor.Docs Nov 27, 2024
@guardrex
Copy link
Collaborator

You might be able to get an answer today by copying this over to a new issue on the product unit's repo at ...

https://github.com/dotnet/aspnetcore/issues

Leave this issue open tho. I think we'll be adding a bit more explanation, and I'll be working the doc update from this issue. This issue will close automatically later when the docs PR merges.

Please add ...

cc: @guardrex https://github.com/dotnet/AspNetCore.Docs/issues/34229

... to the bottom of your opening comment over there so that I can follow the discussion.

@guardrex
Copy link
Collaborator

... but don't be surprised if you don't get an answer from them today. Everyone really is exhausted around here, myself included 😩. I need a nice four-day weekend and a giant 🍽 of 🦃 and cranberry sauce to recover 😋. Everyone is probably bugging out for the weekend as we speak! 🏃‍♂🏃‍♂🏃‍♂🏃‍♂

@MattCost
Copy link
Author

Thanks for the quick response! Opened an issue over there in case there really is a bug.
Enjoy the long weekend!

@guardrex
Copy link
Collaborator

Sure thing ... I'll keep an 👁 on it to see where it goes.

@MattCost
Copy link
Author

MattCost commented Nov 27, 2024

I think the docs def need to be updated somewhere.
PerPage Interactive is the default.
Enhanced Routing is the default.

Using those 2 defaults together causes Persisting Component State to not work.
That note isn't really clearly telling me it wont work.

@guardrex
Copy link
Collaborator

I think global interactive Server is the default, but VS remembers your last selection. Either way, it doesn't matter. This is challenging to cover because it is complicated and touches on several subjects. The interactive routing and enhanced nav coverage in the Routing article and the Prerendering coverage in the Render Modes article might need to be touched-up in addition to the coverage in this dedicated Prerendering article. When I get back next week and based on how your PU issue discussion unfolds, I'll take another look at all of this coverage to see what we can do to improve it. Here are the other places that I mentioned ...

@guardrex
Copy link
Collaborator

Also cross-referencing ... dotnet/aspnetcore#51584

@MattCost
Copy link
Author

but VS remembers your last selection

I didn't use Visual Studio. I used the dotnet cli to make a new blazor app, and edited it with VSCode. The template app chooses to omit the global interactive server attribute in the Routes.razor.

This is challenging to cover because it is complicated and touches on several subjects

Exactly. I started with a default template project, added some sample code from the docs, and when it didn't work, stumbled into the nuances of how all the different blazor options interact with each other.

If the app adopts interactive (enhanced) routing and the page is reached via an internal navigation, prerendering doesn't occur.
I think this line is confusing. Ok, prerendering doesn't occur, but why did the page appear to flicker, and load the data twice?
Well according to this helpful explaination from @javiercn the page is not getting rendered twice due to pre-rendering, but due to a quirk (?) of blazor.

To retain the initial value of the counter during prerendering, Blazor supports persisting state in a prerendered page using the [PersistentComponentState](https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.components.persistentcomponentstate) service (and for components embedded into pages or views of Razor Pages or MVC apps, the [Persist Component State Tag Helper](https://learn.microsoft.com/en-us/aspnet/core/mvc/views/tag-helpers/built-in/persist-component-state?view=aspnetcore-9.0)).

I think maybe just a disclaimer added above this section. Hey LISTEN up! If your app is configured with PerPage Interactivity, and uses Enhanced Navigation, then this PersistantComponentState is not passed between the server side and client side runtimes.

@YuriyDurov
Copy link

YuriyDurov commented Nov 29, 2024

@MattCost I think that line is referring to the navigations happening under an interactive render mode.

You are observing this behavior with the NavMenu navigations, right? The default rendering behavior is that the app globally uses Static SSR and then you can enable interactivity for specific pages.

So what probably happens here is that, even if you enable interactivity on the page itself, the NavMenu is located outside of the scope of the page's interactivity. So the NavMenu behaves as if you are using Static SSR.

Correct me if I am wrong but I believe this could be an explanation to this. The Blazor circuits thing is hard to grasp comprehensively...

Could you try and check if the same behavior persists when the NavLink you are clicking is located inside the scope of the app's interactivity? For example, by enabling interactivity for the entire app or just for the NavMenu. Or by adding another NavLink inside your interactive page and clicking that.

@MattCost
Copy link
Author

So what probably happens here is that, even if you enable interactivity on the page itself, the NavMenu is located outside of the scope of the page's interactivity. So the NavMenu behaves as if you are using Static SSR

Yes this is whats happening. I click the link, first there is a static server side render. Then there is a second interactive (client side?) render since that page is using InteractiveServer render mode. From a noob's perspective, I saw a double flash, and assumed it was just the pre-render / render behavior, and figured PersistComponentState would help (but it didn't). Hence this issue being created.

You are correct. Setting the app to globally use InteractiveServer render mode makes everything behave as expected. Link is clicked, pre-render happens, state is persisted. Second render happens, data is fetched from state.

I'm satisfied with this explanation, just leaving this issue open for @guardrex to work on the docs to explain some of this complex behavior somehow.

@guardrex
Copy link
Collaborator

guardrex commented Dec 5, 2024

UPDATE (12/5): I'm still working my way back to this, but it's going to take a bit more time to reach it. There's internal stuff slowing things down ... holiday vacations ... exhausted devs 😩 (and exhausted doc authors! 🦖😆).

I'm working through backlogged issues, and I'll get back to this as soon as I can ... I hope within the next week or so 🤞🍀.

@guardrex
Copy link
Collaborator

UPDATE (12/20): I wasn't able to get back to this. High priority work slowed me down, but that backlog has been largely cleared out. I'm leaving for the 🎄 holidays and will be back in January. I'll get on this when I get back.

@guardrex
Copy link
Collaborator

guardrex commented Jan 7, 2025

UPDATE (1/7): ... and we're BACK! 😄 Hope everyone is having a Happy New Year! 🎉 I've reached this issue for work, and let's see if I can improve the coverage based on our discussion and the remarks that Javier made on the PU issue.

@guardrex
Copy link
Collaborator

guardrex commented Jan 7, 2025

One of the best things we can do here is cross-link the notes to the PU's issue ...

dotnet/aspnetcore#51584

I'm not saying that's the only change that I'll make, but I think that's critical to surface to devs. It helps explain what's going on, cross-links to other dev PU issues asking about this (including your's, @MattCost), and makes it clear that they're aware of and plan to do something about it. Hopefully, they'll square it away for .NET 10 (November).

@guardrex
Copy link
Collaborator

guardrex commented Jan 7, 2025

Hummmmm 🤔 ... I think I should link the section ...

https://learn.microsoft.com/en-us/aspnet/core/blazor/components/prerender?view=aspnetcore-9.0#interactive-routing-and-prerendering

... into the NOTEs for the examples AND add a cross-link to the PU issue for improving the features.

@guardrex guardrex moved this from P0/P1 - High Priority to In progress in Blazor.Docs Jan 7, 2025
@guardrex guardrex linked a pull request Jan 7, 2025 that will close this issue
@guardrex
Copy link
Collaborator

guardrex commented Jan 7, 2025

The PR is up. This issue will close automatically after the PR merges.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: In progress
Development

Successfully merging a pull request may close this issue.

3 participants