-
Notifications
You must be signed in to change notification settings - Fork 10k
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
Clarify the names of the interactive render modes for Blazor and rationalize with the component tag helper #50636
Comments
We will also need to evaluate the Razor compiler impact if we decide to make this change. @chsienki FYI. |
This is a reasonable step towards clearing up the confusion. Blazor is no longer just about interactive components, although that is the full power of it - with Blazor Web App being server static by default. It is, with lack of a better word, a universal Web component model. I think there is need for some great docs explaining the different hosting models and render modes from this new perspective which even I find hard to define. |
@marinasundstrom See dotnet/AspNetCore.Docs#30279 for our initial attend to get the new Blazor render modes documented and aligned with our existing concepts. This issue was in part inspired by that doc writing effort. |
Thanks for the heads up. I don't think this should impact the compiler; we don't directly rely on the names of the enum, just the underlying interface they represent, so any changes should be transparent to the compiler. |
True, but not a big issue in my opinion, since the older Altogether the older |
I agree that's a real tradeoff. It's obvious that "interactive server mode" is massively clearer than "server mode" for newcomers, so the remaining question is whether it's so verbose that it's actively annoying to more experienced devs. My sense is that it's not annoying at all. |
OK, it sounds like we should move forward with this then.
I don't think the component tag helper is just for back compat. We have lots of MVC & Razor Page developers that may want to embed Blazor components in their existing apps.
I was actually going to open an issue about the possibility of adding it 😄. |
Hey all, just chiming in! A lot of people commented on the naming of the My suggestion would be to separate interactivity from (pre)rendering, as the two concepts play together but are quite different and are mostly two independent choices that one can make. In my mind, that would imply renaming the
And then the pre-render flag would also turn into a directive or an enum, that states if the component should be pre-rendered. Pre-rendered component with server based interactivity: @interactivemode Server
@prerendered
<h1>My component</h1>
@code {
// some code
} Calling a pre-rendered component with client based interactivity: <Counter @interactivemode="Client" @prerendered /> Component that explicitly sets no interactivity (could also serve as a workaround for enabling interactivity globally in the root component): @interactivemode None
@* Using prerendered here would be a NOP *@
<h1>My component</h1> But I don't know if that would be possible due to backwards compatibility or other constraints that I missed, so please take it like a very surface level suggestion. |
@SteveSandersonMS |
Thanks for the suggestions. At this point coming into RC2 we need to avoid compiler-impacting changes, or other changes that would force large amounts of framework API churn, so we're really only considering direct renames of what already exists. We have enough consensus to proceed with |
Totally understand. :) |
Hi guys! Could you shed some light why you picked static mode as the default? Do you plan to keep it that way? Won't it hurt developer productivity as people would have to always check whether We (the maintainers of Radzen.Blazor) already started receiving bug reports that components are not working in .NET 8 Blazor apps so I wanted to ask what the rationale for this breaking (IMHO) behavior was. |
Yes, the high-level goal for Blazor in .NET 8 is to make it a first-class choice for a wider range of web UI scenarios before. In the past, Blazor could only be used for SPA-like apps, either with Server or WebAssembly hosting. Both of those hosting models are great in some cases and limiting in other cases. In particular, neither are ideal for high-traffic, read-only public websites where you simply want to generate and return some stateless HTML as fast and cheaply as possible. So with .NET 8 we're following a similar architectural pattern that's become mainstream in other technologies in the last year (e.g., Next.js, Nuxt, SvelteKit, and others) whereby components by default are executed statelessly on the server, and hence do produce static HTML extremely quickly and with no hosting overhead from WebSocket connections or requiring the end user to download a .NET WebAssembly runtime. For cases where apps only need to produce HTML with forms (that can be posted back to the server), links, etc., you can now do so with Blazor's modern component programming model as an alterative to Razor Pages, MVC views, etc. Then, it becomes more powerful still in cases where people do want to enable stateful interactivity on particular parts of the site, as it's possible to tag individual pages or components with a chosen rendermode. And we've also made it possible to mix Server and WebAssembly in the same app, and added Auto which dynamically switches to maximize startup speed and minimize hosting cost. For example, this is likely to be something people would do on an "admin" or "control panel" part of a site. This isn't a breaking change (as we define it) because existing apps continue to work the same, and we've not withdrawn any functionality. We've just added a new, additional way to run a Blazor app, which has different strengths and limitations. Of course, full end-to-end SPA apps remain a central scenario for Blazor, either with Server or WebAssembly hosting. So we've just updated the project template to have a one-click way to get a more traditional Blazor app that's interactive from the root level down, i.e., so every page and component is interactive. This means you don't get stateless HTML generation but you do get stateful event support. It's up to developers to choose what best matches their scenarios. We've been talking about this heavily from the beginning of .NET 8 and there are dozens of blog posts, videos, etc about it. I know not every developer in the Blazor world will have been reached by these yet, and everyone who starts with it will have some shifts of mental model to deal with (except if they just use global interactivity as mentioned above). The overall payoff is being able to use the same programming model, and often the same components, for super high-scale public HTML sites as well as for rich interactive SPAs, even in the same site. Hope that makes sense. In terms of why the default is stateless:
We also know we need to provide more detail and guidance for component authors on how to make the best use of new capabilities. This is tracked at #47624 and should be done as part of finalizing .NET 8. |
Thank you for the elaborate response @SteveSandersonMS. I appreciate the insights. I fully agree with the direction you have taken and see the value of static mode. I just wish it weren't the default as I see it causes confusion (in me and other fellow Blazor developers). All the Blazor applications I've seen (hundreds) were stateful and every component had some sort of interaction. I guess we just have to adapt with the new state of matters. A few followup questions:
|
|
Thanks!
Does it mean that the "older" SPA Blazor apps are now gone from the template or are they behind some option which is not yet implemented in |
In .NET 8 there is:
Sorry I was wrong above when I said that .NET 8 doesn't contain the |
…des. (#50684) Fixes #50433 (Add root level interactivity option) Fixes #50646 (Remove workaround for Counter component) Fixes #50636 (Clarify the names of the interactive render modes) In terms of the code we now emit, there should be nothing controversial here. The template just has to do quite a bit of if/else in many places to account for all these options and how rendermodes are used and not used based on them. The PR is big because the renames have really wide impact, but almost all the "files changes" are just due to renames. The only real code changes are in the project templates. # Testing impact Adding this option, the BlazorWeb template now has **so many** possible combinations of options, including: - Whether or not to enable Server interactivity - Whether or not to enable WebAssembly interactivity - Whether or not to be interactive from the root - Whether or not to include sample content - Whether or not to use ProgramMain So that's around 32 combinations of output - without even accounting for auth options! We don't currently have E2E verification of any of them, as those tests are skipped due to unreliability. We're going to have to lean hard on CTI validations for this, and make sure all the important combinations are covered - cc @mkArtakMSFT. # Options design update Having a list of 6 separate checkboxes in VS is pretty unpleasant and hard to understand: <img src="https://github.com/dotnet/aspnetcore/assets/1101362/93713e83-0793-4140-82e1-95ca63580e3d" width="500" /> So, in this PR I'm proposing (and have implemented, but we can still change it), a change to use dropdowns for the interactivity type and location options. This reduces the number of inputs by one, and means they can be more self-describing: <img src="https://github.com/dotnet/aspnetcore/assets/1101362/649c93fd-d464-499c-b1f2-36436ebf4e3c" width="500" /> * The "interactivity type" choices are: * **None** * **Server** (default) * **WebAssembly** * **Auto (Server and WebAssembly)**. * The "interactivity location" choices are: * **Per page/component** (default) * **Global** Note that "interactivity location" is disabled if interactivity type == "None", but [only CLI honors that right now](dotnet/templating#5648) (VS should add support later, and until then, location will have no effect if there's no interactivity). I think this is much easier to understand, since you no longer have to infer that enabling both Server and WebAssembly means you're going to get Auto. It's also much better in the CLI, since it was completely ridiculous before that `--use-server` defaulted to true but `--use-wasm` defaulted to false, so to get WebAssembly you needed to set `--use-server false --use wasm`. Now you would say `--interactivity webassembly` (and not `wasm` - that was weird too). ![image](https://github.com/dotnet/aspnetcore/assets/1101362/0b4751ad-f91b-4bac-8edf-9e31aa761fbf)
What is the flag which makes |
We only just merged the project template update that enables this: #50684. The flag is |
Thank you for the clarification. I got it now. |
Done in #50684 |
@EmilAlipiev Looks like you're using mismatched package versions. When we updated the names, we did so consistently. The new API is |
@SteveSandersonMS thanks for the hint. After cleaning bin obj rebuild etc. exact error was displayed. Probably this was asked before but I am curious why needed to name it "Interactive" explicitly? is it not always interactive if not static rendering? |
Blazor has two server-side rendering modes: static and interactive. So just using "Server" for interactive server rendering was ambiguous. We added the "Interactive" prefix to make the distinction clear. And once we did that for interactive server rendering we decided it made sense to do for all the interactive render modes. |
In .NET 8 we have the following render modes for Blazor components:
We also have the existing component tag helper that defines its own RenderModes enum:
One problem with the current naming scheme is that "Server" is a bit ambiguous and confusing. Both the Static and Server render modes render from the server, so it's not immediately clear what the "Server" render mode means.
We could clarify this by renaming Server to something more specific, like InteractiveServer. If we do that, we presumably should to rename the other interactive render modes for consistency:
Note that this also impacts the APIs used to configure and enable these render modes:
AddServerComponents()
->AddInteractiveServerComponents()
, etc.The
RenderMode
enum used by the component tag helper has already shipped. If we change names of the new render modes, then they will be inconsistent with the existing enum. So, we need to decide if we care more about clarity with the new API or consistency with the existing ones. The new names are also more verbose.The text was updated successfully, but these errors were encountered: