When I first pulled the Blazor Server beta out of the box in 2019, I was surprised how quickly the SignalR loop let me prototype a dashboard.
Blazor Server’s tight SignalR loop gives me a dev cycle that feels like writing a desktop app, but with a web front. The server‑side rendering means no WASM download, so the first paint comes in under a second on a LAN. The catch is that every click trips a round‑trip to the server. In an intranet, that latency is invisible, but on a global web app it can feel like a lagging game.
For example, I worked on a Blazor Server app with about 50 users, and the round-trip time was around 10-20 milliseconds. However, when we deployed the same app to a global audience, the round-trip time increased to around 100-200 milliseconds, which was noticeable. To mitigate this, we used caching and optimized our database queries to reduce the load on the server.
Blazor WebAssembly runs a full .NET runtime in the browser. After a 1‑to‑3 second download of the WASM runtime and my app DLLs, the UI stays on the client and no server round‑trip is needed. That makes it a natural fit for offline use, PWA installs, or when I want the browser to do the heavy lifting. The initial load is the price I pay.
I’ve seen this initial load become a significant issue for users with slow internet connections. For instance, in one of our apps, the initial load time was around 2 seconds on a fast connection, but it increased to around 10 seconds on a slow connection. To address this, we used tools like Webpack and Brotli compression to reduce the size of our app and improve load times.
IJSRuntime lets me call JavaScript from C# and back. In production I use it for clipboard access, geolocation, WebSockets, and to hook into charting or rich‑text editors that only exist in JS. It works, but the more I rely on it, the more the codebase feels like a hybrid of two worlds. If you need a lot of JavaScript, a pure JS front‑end with a .NET API might be less painful.
Using IJSRuntime can also introduce security risks if not handled properly. For example, if you’re not careful, you can expose your app to XSS attacks. To mitigate this, we use tools like Content Security Policy and ensure that all JavaScript code is properly sanitized before executing it. This adds an extra layer of complexity, but it’s necessary for securing our apps.
The component libraries have come a long way. Syncfusion, Radzen, MudBlazor, and Blazorise now ship full data grids, charts, and form controls. MudBlazor, the open‑source Material Design set, has become the go‑to for many line‑of‑business apps I’ve built. The gap that existed at launch, where I had to roll my own controls, is closed.
In the intranet, Blazor Server feels like a desktop app with a web shell. The server sits next to the user, so round‑trip latency is a fraction of a millisecond. I can push updates instantly and keep the UI state in sync without worrying about client‑side state drift.
For a global audience, WebAssembly shines when I need offline support or low‑bandwidth interactions. The initial 1‑to‑3 second download can hurt first‑time users, but once cached the experience is snappy. I’ve seen users in rural areas get the same feel as those on fiber.
If the app is heavy on third‑party JavaScript, I’ve found that starting with a JavaScript framework and wiring it to a .NET API keeps the code cleaner. Blazor is great for tight coupling between UI and server logic, but not every scenario fits that model.