Blazor Server in .NET Core 3.0 scenarios and performance

Daniel Roth

Since the release of Blazor Server with .NET Core 3.0 last month lots of folks have shared their excitement with us about being able to build client-side web UI with just .NET and C#. At the same time, we’ve also heard lots of questions about what Blazor Server is, how it relates to Blazor WebAssembly, and what scenarios Blazor Server is best suited for. Should you choose Blazor Server for your client-side web UI needs, or wait for Blazor WebAssembly? This post seeks to answer these questions, and to provide insights into how Blazor Server performs at scale and how we envision Blazor evolving in the future.

What is Blazor Server?

Blazor Server apps host Blazor components on the server and handle UI interactions over a real-time SignalR connection. As the user interacts with the app, the UI events are sent to the server over the connection to be handled by the various components that make up the app. When a component handles a UI event, it’s rendered based on its updated state. Blazor compares the newly rendered output with what was rendered previously and send the changes back to the browser and applies them to the DOM.

Blazor Server

Since Blazor Server apps run on .NET Core on the server, they enjoy all the benefits of running on .NET Core including great runtime performance and tooling. Blazor Server apps can leverage the full ecosystem of .NET Standard libraries without any browser imposed limitations.

When should I use Blazor Server?

Blazor Server enables you to add rich interactive UI to your .NET apps today without having to write JavaScript. If you need the interactivity of a single-page app in your .NET app, then Blazor Server is a great solution.

Blazor Server can be used to write completely new apps or to complement existing MVC and Razor Pages apps. There’s no need to rewrite existing app logic. Blazor is designed to work together with MVC and Razor Pages, not replace them. You can continue to use MVC and Razor Pages for your server-rendering needs while using Blazor for client-side UI interactions.

Blazor Server works best for scenarios where you have a reliable low-latency network connection, which is normally achieved when the client and server are geographically on the same continent. Apps that require extremely high fidelity instant updates on every tiny mouse twitch, like real-time games or drawing apps, are not a good fit for Blazor Server. Because Blazor Server apps require an active network connection, offline scenarios are not supported.

Blazor Server is also useful when you want to offload work from the client to the server. Blazor Server apps require only a small download to establish the connection with the server and to process UI interactions. All the hard work of running the app logic and rendering the UI is then done on the server. This means Blazor Server apps load fast even as the app functionality grows. Because the client side of a Blazor Server app is so thin, it’s a great solution for apps that need to run on low-powered devices.

Using Blazor Server at scale

Blazor Server can scale from small internal line of business apps to large internet scale apps. While .NET Core 3.0 was still in preview we tested Blazor Server to see what its baseline scale characteristics look like. We put a Blazor Server app under load with active clients and monitored the latency of the user interactions. In our tests, a single Standard_D1_v2 instance on Azure (1 vCPU, 3.5 GB memory) could handle over 5,000 concurrent users without any degradation in latency. A Standard_D3_V2 instance (4 vCPU, 14GB memory) handled well over 20,000 concurrent clients. The main bottleneck for handling further load was available memory. Will you see this level of scale in your own app? That will depend in large part on how much additional memory your app requires per user. But for many apps, we believe this level of scale out is quite reasonable. We also plan to post additional updates on improvements in Blazor Server scalability in the weeks ahead. So stay tuned!

What is Blazor WebAssembly?

Blazor is a UI framework that can run in different environments. When you build UI components using Blazor, you get the flexibility to choose how and where they are hosted and run. As well as running your UI components on the server with Blazor Server, you can run those same components on the client with Blazor WebAssembly. This flexibility means you can adapt to your users’ needs and avoid the risk of being tied to a specific app hosting model.

Blazor WebAssembly apps host components in the browser using a WebAssembly-based .NET runtime. The components handle UI events and execute their rendering logic directly in the browser. Blazor WebAssembly apps use only open web standards to run .NET code client-side, without the need for any browser plugins or code transpilation. Just like with Blazor Server apps, the Blazor framework handles comparing the newly rendered output with what was rendered previous and updates the DOM accordingly, but with Blazor WebAssembly the UI rendering is handled client-side.

Blazor WebAssembly

When should I use Blazor WebAssembly?

Blazor WebAssembly is still in preview and isn’t yet ready for production use yet. If you’re looking for a production ready solution, then Blazor Server is what we’d recommend.

Once Blazor WebAssembly ships (May 2020), it will enable running Razor components and .NET code in the browser on the user’s device. Blazor WebAssembly apps help offload work from the server to the client. A Blazor WebAssembly app can leverage the client device’s compute, memory, and storage resources, as well as other resources made available through standard browser APIs.

Blazor WebAssembly apps don’t require the use of .NET on the server and can be used to build static sites. A Blazor WebAssembly app is just a bunch of static files that can be hosted using any static site hosting solution, like GitHub pages or Azure Static Website Hosting. When combined with a service worker, a Blazor WebAssembly app can function completely offline.

When combined with .NET on the server, Blazor WebAssembly enables full stack web development. You can share code, leverage the .NET ecosystem, and reuse your existing .NET skills and infrastructure.

Including a .NET runtime with your web app does increase the app size, which will impact load time. While there are a variety of techniques to mitigate this (prerendering on the server, HTTP caching, IL linking, etc.), Blazor WebAssembly may not be the best choice for apps that are very sensitive to download size and load time.

Blazor WebAssembly apps also require a browser that supports WebAssembly. WebAssembly is supported by all modern browsers, including mobile and desktop browsers. However, if you need to support older browsers without WebAssembly support then Blazor WebAssembly isn’t for you.

Blazor WebAssembly is optimized for UI rendering scenarios, but isn’t currently great for running CPU intensive workloads. Blazor WebAssembly apps today use a .NET IL interpreter to execute your .NET code, which doesn’t have the same performance as a native .NET runtime with JIT compilation. We’re working to better address this scenario in the future by adding support for compiling your .NET code directly to WebAssembly instead of using an interpreter.

You can change your mind later

Regardless of whether you choose Blazor Server or Blazor WebAssembly, you can always change your mind later. All Blazor apps use a common component model, Razor components. The same components can be hosted in a Blazor Server app or a Blazor WebAssembly app. So if you start with one Blazor hosting model and then later decide you want to switch to a different one, doing so is very straight forward.

What’s next for Blazor?

After shipping Blazor WebAssembly, we plan to expand Blazor to support not just web apps, but also Progressive Web Apps (PWAs), hybrid apps, and even fully native apps.

  • Blazor PWAs: PWAs are web apps that leverage the latest web standards to provide a more native-like experience. PWAs can support offline scenarios, push notifications, and OS integrations, like support for pinning the app to your home screen or the Windows Start menu.
  • Blazor Hybrid: Hybrid apps are native apps that use web technologies for the UI. Examples include Electron apps and mobile apps that render to a web view. Blazor Hybrid apps don’t run on WebAssembly, but instead use a native .NET runtime like .NET Core or Xamarin. You can find an experimental sample for using Blazor with Electron on GitHub.
  • Blazor Native: Blazor apps today render HTML, but the renderer can be replaced to render native controls instead. A Blazor Native app runs natively on the devices and uses a common UI abstraction to render native controls for that device. This is very similar to how frameworks like Xamarin Forms or React Native work today.

These three efforts are all currently experimental. We expect to have official previews of support for Blazor PWAs and Blazor Hybrid apps using Electron in the .NET 5 time frame (Nov 2020). There isn’t a road map for Blazor Native support yet, but it’s an area we are actively investigating.

Summary

With .NET Core 3.0, you can build rich interactive client-side UI today with Blazor Server. Blazor Server is a great way to add client-side functionality to your existing and new web apps using your existing .NET skills and assets. Blazor Server is built to scale for all your web app needs. Blazor WebAssembly is still in preview, but is expected to ship in May of next year. In the future we expect to continue to evolve Blazor to support PWAs, hybrid apps, and native apps. For now, we hope you’ll give Blazor Server a try by installing .NET Core 3.0!

62 comments

Discussion is closed. Login to edit/delete existing comments.

  • Jonas Lomholdt 0

    This is very cool! I’m looking very much forward to see how far you will take Blazor in the future. It seems the possibilities are endless 👍🏼

  • Adan Jauregui 0

    It would be great for Blazor Native plans to be extensible enough to be a .NET cross-platform UI development framework correctly adapted to the UI libraries provided by the operating systems.

    • Nitin Sawant 0

      blazor + xamarin = .NET cross-platform razor UI development

  • Vincent Wright 0

    I like Blazor so far. The only issue is the constant loss of connection with the backend that requires the front end to refresh over and over again. It would be great if that worked better. I don’t like having to refresh the page every 5 minutes.

    • Daniel RothMicrosoft employee 0

      Hi Vincent,

      Are you seeing this just during development or in production? During development, Visual Studio will rebuild and restart the app when code file changes are made. This will result in the browser losing the connection and not being able to recover because all the server state is gone, so you need to refresh the browser to see the changes. The dev workflow is then edit, save, refresh.

      You shouldn’t see the connection get lost and require an browser refresh in production unless something is killing the app process on the server. If you’re having issues with this please file an issue and we’ll take a look: https://github.com/aspnet/aspnetcore/issues.

      • Vincent Wright 0

        I see it in production mostly. But, I have noticed it on development even when I make no changes.

        • Daniel RothMicrosoft employee 0

          Check to see how often the server is being restarted or recycled. You can also try setting up your app to automatically refresh as described here: https://github.com/aspnet/AspNetCore/issues/10325#issuecomment-537979717.

          I don’t know why you would see a connection drop during development without making a file change. If you can reproduce the issue reliably, please let us know by filing a GitHub issue.

          • Vincent Wright 0

            I will see. This is hosted on a hosting provider, so I don’t have access to their logs. Just the generic logs. Any way to reliably know if they are resetting the connection? It happens about every 2 minutes. I was able to get it stable on production. I also implemented the refresh code and it works, but I would like to fix it properly.

          • Sebastiaan Dammann 0

            Blazor uses websockets, server sent events and long polling. The latter two are fallbacks. You might need to have websockets enabled on your hoster. I can imagine long polling connections are terminated.

          • Daniel RothMicrosoft employee 0

            Yeah, I agree with Sebastiaan that this might be an issue with using a transport other than WebSockets. Long polling should still work though. You can verify which transport is being used by looking at the browser console output and network trace. You might want to open an issue on GitHub with details about your setup so that we can better assist you.

      • Phuc Tran 0

        May I suggest Abiosoft.DotNet.DevReload, since in most case in dev workflow, a refresh is needed anyway

  • Sebastiaan Dammann 0

    I very much enjoy working with Blazor Server. I’m currently building a retrospective app in it (similar to retrium). I like the almost no-effort real-time UI and state broadcasting that’s possible with Blazor. It does some time getting rid of the classic request/response mindset.

    Three things that annoy me a bit:
    – with edit and continue enabled I constantly get a “cannot continue because of code changes”
    – error handling is cumbersome, and almost everything is destructive to the current session. And if something happens, the user doesn’t see any indication something happened.
    – there appears to be no way to automatically test components

    • Daniel RothMicrosoft employee 0

      Thanks for this feedback, Sebastiaan!

      Have you filed a GitHub issue or Visual Studio feedback issue for the edit-and-continue issue you are seeing? It sounds like we should look into that.

      I’d love to get more details on what parts of error handling are cumbersome. Please also see our doc on error handling in Blazor.

      There are a couple of community projects for testing components that you should check out:
      http://blog.stevensanderson.com/2019/08/29/blazor-unit-testing-prototype/
      https://github.com/egil/razor-components-testing-library

      • Sebastiaan Dammann 0

        Hi Daniel,

        I’d love to get more details on what parts of error handling are cumbersome.

        The need to litter every callback with a try/catch mechanism to contain errors and show an error message. Having a global or per-component error handling routine would be nice. Some errors, like errors during callbacks are recoverable.

        In addition to the above, in some conditions an unhandled error won’t be visible to the user anymore. The user interface will be unresponsive and there does not appear to be way to show a general message that something went wrong.

        I also like to be able to attach loading logic while a callback or event is performed (or are events performed synchronously?).

        There are a couple of community projects for testing components that you should check out

        Yes, the latter is simply an HTML output matcher. The former doesn’t have a license so I cannot incorporate the testing code in my GPLv3 project, but allows to check for “interesting” points in the output.
        I believe that both approaches don’t allow “mocking” a component.

    • Hallam 0

      I think “– with edit and continue enabled I constantly get a “cannot continue because of code changes” Is not a problem from Blazor but Visual Studio itself. Sometimes without changing any code, first time something hits a breakpoint I get that whilst in a UWP project.

  • Mark Deanil Vicente 0

    Blazor has a bright future! 🙂

  • Gareth Doherty 0

    I simply cannot wait for the notion of Blazor Native apps. The Blutter demo blew me away earlier in the year.

  • Michael Washington 0

    Thank you for posting this. I have been using Blazor for numerous projects for the past few months with no issues other than users on the other side of the world experiencing ‘sluggish’ connections. People in the same continent as me, no problems 🙂 Also, I host most of my server side Blazor projects on an Azure D1 plan (1 GB memory – $9 a month) but I make sure to go into -Configuration- then -General Settings- select “on” for -Web sockets- and then click the -Save- button.

  • Peter N. Moore 0

    Hey Dan thanks for this info! Is the source code for the Blazor server-side app you tested under stress available on Github anywhere? And what load testing framework did you use? Thanks!

    • Daniel RothMicrosoft employee 0

      Hi Peter,

      Not yet, but we are putting together a follow up blog post that will go into more detail on how we test scale out for Blazor Server and we will expect to share the infrastructure code at that point. The apps we tested were the default Blazor template and a Blazor Server port of the Blazing Pizza app used for the Blazor workshop (https://aka.ms/blazorworkshop).

      • Marc Greiner 0

        Hi Daniel,

        How does a Blazor Server app compare to a similar web app built with classical technologies, in term of concurrent users, memory, responsiveness?
        For example Blazor Server vs. ASPx?

      • Peter N. Moore 0

        That will be great, thanks!

  • Christophe Peugnet 0

    Thank you very much for this information. For one month I have been working at 75% on Blazor. That’s just great! Thank you for your work

  • Ben Hayat 0

    Daniel, now that you guys are working on the Blazor client, PLEASE be sure we will get a C# Blazor Client library to connect to IdentityServer4 to give feature like adding new users, login/logout, password reset and etc. IS4 provides one for JS client library, but we need one for Blazor by release date.
    Thanks!

    • Daniel RothMicrosoft employee 0

      Absolutely – thanks for this feedback!

Feedback usabilla icon