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] Application models #51579

Open
javiercn opened this issue Oct 23, 2023 · 0 comments
Open

[Blazor] Application models #51579

javiercn opened this issue Oct 23, 2023 · 0 comments
Labels
area-blazor Includes: Blazor, Razor Components Docs This issue tracks updating documentation

Comments

@javiercn
Copy link
Member

Describe the ways in which interactivity can be added to an existing app and the trade offs for each option. A rough sketch is below:

Blazor web application models

Blazor web is the new version of the ASP.NET Component model that extends the capabilities of the current Blazor Server and Webassembly applications with support for Server Side Rendering (also known as prerendering) and traditional server side features like form handling.

Blazor web enables developers to render the entire UI using just Blazor components. This means that you don't need a root HTML or _Host.cshtml page as you did in Blazor WebAssembly and Blazor Server, and instead you can render the entire UI using just components.

Blazor Web integrates with ASP.NET Core's routing and middleware to enable features like form handling, authentication, authorization, and more. Routing and navigation in Blazor Web applications happens server side by default, although you can also use client side routing.

Whether the app uses server-side routing or client-side routing is up to the app. The main difference between the two approaches is whether app state is preserved across pages.

  • With server-side routing, app state is not preserved across pages, which means that when you navigate to a different page, for example, by clicking a button, any state in memory is lost1.
  • With client-side routing, app state is preserved across pages, which is the

1: The state in memory might be preserved when using enhanced navigation and the runtime remains loaded, but this is not guaranteed and should not be relied upon.

Apps with server-side routing

This is the default for new Blazor Web applications. The majority of the apps do not require a high degree of interactivity that justifies using Blazor WebAssembly and Blazor Server, they can instead be handled through static server side rendering as many sites and applications did in the past.

It is for this reason that it makes sense for routing to happen on the server (as doing it client-side inmediately requires a webassembly runtime or a SignalR connection). Instead, we think it is better in general to render the UI server-side in most situations and rely on interactivity on specic pages that benefit form it.

sequenceDiagram
    participant User
    participant Browser
    participant Server
    Browser->>Server: Request for '/'
    Server->>Server: ASP.NET routing middleware (find endpoint for '/')
    Server->>Server: Render root component for endpoint '/' (Typically App.razor, the equivalent of rendering _Host.cshtml)
    alt Router component rendered inside App.razor
        Server->>Server: Router component render page identified for '/'
    end
    Server->>Browser: HTML for '/'
    alt App.razor rendered blazor.web.js
        Browser->>Server: initialize interactive components
    end
    User->>Browser: clicks on a link to '/counter'
    Browser->>Server: Request for '/counter'
    Server->>Server: ASP.NET routing middleware (find endpoint for '/counter')
    Server->>Server: Render root component for endpoint '/counter' (Typically App.razor, the equivalent of rendering _Host.cshtml)
    alt Router component rendered inside App.razor
        Server->>Server: Router component render page identified for '/counter'
    end
    Server->>Browser: HTML for '/counter'
    alt App.razor rendered blazor.web.js
        Browser->>Server: initialize interactive components
    end
Loading

Apps with client-side routing

This model can be thought as the evolution of the current Blazor Server and Web assembly models, as its in essence an improved version of that model that enables better prerendering. To understand the difference here is what a Blazor WebAssembly or Blazor Server app worked like, and here is how a Blazor Web app works in comparison.

sequenceDiagram
    participant User
    participant Browser
    participant Server
    Browser->>Server: Request for '/'
    Server->>Server: ASP.NET routing middleware (match fallback route '{**path:nonfile}' and return index.html for webassembly or render _Host.cshtml for Blazor Server)
    Server->>Browser: HTML for '/'
    alt WebAssembly
        Browser->>Browser: blazor.webassembly.js initializes interactive components
    else Blazor Server
        Browser->>Server: blazor.server.js initializes interactive components by creating a circuit,<br> which is a "stateful session" between the browser and the server via a SignalR connection.
    end
    User->>Browser: clicks on a link to '/counter'
    alt WebAssembly
        Browser->>Browser: blazor.webassembly.js intercepts the navigation and the client-side router renders a new page in response
    else Blazor Server
        Browser->>Server: blazor.server.js handles navigation by sending a message to the server and the "interactive" router component handles the navigation and produces a new render in response.
    end
Loading

In contrast, here is how a Blazor Web app works with either an interactive webassembly or server router:

sequenceDiagram
    participant User
    participant Browser
    participant Server
    Browser->>Server: Request for '/'
    Server->>Server: ASP.NET routing middleware (match endpoint for a given request and render root component (typically App.razor))
    Server->>Server: App.razor renders a component that defines the render mode (typically Routes.Razor) which inside contains a router component
    Server->>Server: Router component reuses the results from the ASP.NET routing middleware to render the page for '/'
    alt WebAssembly
        Browser->>Browser: blazor.webassembly.js initializes interactive components including the router component
    else Blazor Server
        Browser->>Server: blazor.server.js initializes interactive components including the router
    end
    User->>Browser: clicks on a link to '/counter'
    alt WebAssembly
        Browser->>Browser: The router component running on the page intercepts the navigation and renders a new page in response.
    else Blazor Server
        Browser->>Server: The router component running on the page intercepts the navigation,<br> sends a message to the server and the "interactive" router component handles the navigation and produces a new render in response.
    end
Loading

With this in mind, the main differences between the old model and the new model are:

  • Prerendering doesn't use a fallback route. Instead, it can use the page information on the app components to decide what routes to handle. This is useful as it avoids incorrectly serving HTML for missing endpoints.
  • The app is completely prerendered using Components, without the need for an additional index.html page or a _Host.cshtml page to produce the top level wrapping HTML of the interactive components.
  • With webasembly, prerendering becomes much easier, as the app is already setup to do so.
@dotnet-issue-labeler dotnet-issue-labeler bot added the area-blazor Includes: Blazor, Razor Components label Oct 23, 2023
@mkArtakMSFT mkArtakMSFT added the Docs This issue tracks updating documentation label Oct 23, 2023
@mkArtakMSFT mkArtakMSFT added this to the .NET 8: Documentation milestone Oct 23, 2023
@dotnet-policy-service dotnet-policy-service bot added the pending-ci-rerun When assigned to a PR indicates that the CI checks should be rerun label Feb 6, 2024
@wtgodbe wtgodbe removed the pending-ci-rerun When assigned to a PR indicates that the CI checks should be rerun label Feb 6, 2024
@dotnet-policy-service dotnet-policy-service bot added the pending-ci-rerun When assigned to a PR indicates that the CI checks should be rerun label Feb 6, 2024
@wtgodbe wtgodbe removed the pending-ci-rerun When assigned to a PR indicates that the CI checks should be rerun label Feb 13, 2024
@dotnet dotnet deleted a comment from dotnet-policy-service bot Feb 13, 2024
@dotnet dotnet deleted a comment from dotnet-policy-service bot Feb 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-blazor Includes: Blazor, Razor Components Docs This issue tracks updating documentation
Projects
None yet
Development

No branches or pull requests

3 participants