A decision has been made. Blazor is happening. Hooray! But what now? Do you just scaffold the app in the IDE and start typing? Of course, you could… That’s exactly what you should do when you’re exploring, learning, investigating.
How to start a blazor project right: table of contents
At some point, however, the time will come to start something professional. Let’s make one thing clear – your specific case might require a unique approach. Don’t implement something just because it’s considered standard or the template tells you to do so. Improve your knowledge, bend it around your problem. Not the other way around.
The first architectural decision that you’ll have to make is between Blazor Server and Blazor WebAssembly. The difference between them comes down to the limits and possibilities of their hosting environments.
Pros and cons of a Server-side solution
Should the app be fully hosted on a server, its runtime and libraries won’t have to be downloaded to the user’s device, achieving very fast render time. Even faster with prerender options enabled. This also means that method execution will be happening in an environment that the administrator has full control over. Whatever is needed to run the app, can be preinstalled, which makes development virtually boundless. It also makes the app compatible with pretty much any browser out there. That’s especially important if it needs to still be available for IE 11 or other older browsers. The server-side project will also be the most similar to building a legacy MVC application or an API project. Same principles and logic could be applied, so the developers’ onboarding process should be quick and efficient.
On the other hand, the biggest challenge that you will face with Blazor-server is its scalability. Should you work with Azure, most of the heavy lifting could be done for you after a proper configuration is put in place. In other hosting cases, you’d have to be managing all that yourself. Every user is going to have a dedicated SignalR connection established. That also means request/response communication is completely different than in a standard web app. Memory consumption can very quickly get out of hand. Considering that all communication is going through that on established pipeline, rather than reloading full-page, network latency has to be closely monitored and change package sizes reduced whenever possible. The last downside, that has to be taken into accountis lack of offline support. These days it’s becoming an expected feature rather than a nice-have.
What to keep in mind in a Blazor Server project?
- if you have any prior experience building web applications, there’s very little that will be different when you switch to Blazor Server.
- all static files will be stored in wwwroot directory
- configuration files should be placed in the main project directory
- when it makes sense, split CSS scripts into smaller chunks, take advantage of Blazor supporting per-component CSS files as well as CS code-behind classes
- understanding SignalR communication
- keeping “changed” markup scope small to take full advantage of fractured communication
- service lifetimes will behave differently, as one request may be active as long as the socket connection is active
- following standard AddDbContext() syntax to register database connection could be problematic, as by design its lifetime is AsScoped() – what’s a DbContextFactory?
- tracking active users in comparison to app performance – what’s a CircuitHandler?
Blazor Client-side – for and against
Upon the first request, the entire application is downloaded into the user’s browser. That means that all the internal logic is managed entirely on the user’s device, which results in very fast user experience. App reactions should be instantaneous for the user, except for any external API calls, which have to wait for a response. This also has another implication: hosting the WebAssembly app doesn’t require a running server. It could be run fully serverless! It’s even Microsoft’s suggested choice to host it as a Static Web Application, as this both limits costs and improves stability. Another advantage of WASM is offline support. Yes, that means the app can be run without an Internet connection, but it doesn’t mean that your web application will suddenly turn into a native one. It will be cached, giving a native feeling, but still running in a browser-like shell, with all its security and all its limitations.
Security will be the biggest concern, should Blazor Client-side be the choice. As the entire app is pulled into the user’s browser, it can be exposed there with a bit of digging. That said, all your confidential data or business logic should be provided through an API rather than within the application itself. Of course, you could go for encryptions, but an external provider would be much more efficient and again – secure. The other thing that may be a downside, if not managed properly, is initial page load. The heavier your compiled application is, the longer its user will have to wait for it to load. A couple of improvements were introduced to help with that, but in the end it’s still on the developer to make the solution light and efficient. Lean on APIs for whatever doesn’t have to be available locally.
What to keep in mind in a Blazor WebAssembly project?
- all static files are still stored in wwwroot directory
- that directory is deployed with the app into the user’s browser
- should you have configuration files that are required, those should also be placed in that directory
- offline support requires manifest.json file to be available and shipped to the browser as well.
- keeping application weight low to improve page load time – what is Runtime Relinking?
- keeping application compilation time low to ship app packages faster – what is AOT Compilation?
- separating sensitive parts from the ones that could be freely shared.
- application state management as it’s persisted only in-browser.
- logging – what is Cloud Logging?
Mix and match – wait, what?
Is it possible to get the best of both worlds? Yes and with that managing the challenges of each could become easier. There is a possibility to have a mix of Server-side and WebAssembly in your project. Those would be two separate processes, running independently but capable of talking to each other. Can WASM and SignalR be available for the same page or document? No, not yet, looking at the Blazor 2022 Roadmap, it might be coming pretty soon!
Mixing will make your entire structure more complex, but are there any benefits to it ? First, leveraging different memory allocations. Blazor Server-side is going to persist all active sockets and sessions on the server. In WASM the entire memory load is taken on by the user’s browser. If you have complex business logic to be executed upon page load, this could be a responsibility of the part of the app hosted on the Server, while WebAssembly just persists the application state. Both sides keep their sensitive data secured and inaccessible until allowed otherwise. So, if the user part of the application is lightweight, it could be built as Blazor Client-side, improving responsiveness and reducing hosting costs. Blazor Server-side would then be responsible for providing bigger app chunks when those are requested.
With that, I’d say the benefits of mixing are sometimes worth the increased complexity.
So many options, do I make a choice?
As I’ve elaborated in a previous article, making a choice always comes down to the particular challenge and point-of-view. Now that you know most of the pros, cons, and challenges of each hosting option, making a decision should be easier.
For small projects, keep it simple. There’s no need to overdo it when a cheap server could handle all the app load or when nothing sensitive would be happening inside the WebAssembly app. Keep the complexity of the Mixed solution for complex portal solutions, which bring on all the challenges of scalability, responsiveness, and security.
Whatever you choose and especially if you are not certain what will be the best option in the future, here is one last piece of advice: encapsulate your components as much as possible into an independent library. That way, if you ever decide to switch to a server-side or client-side solution or even a new Blazor app type that might come up in the future, the transition will be much easier and it will come down to simply adjusting Startup files and configuration.
By the time you got here, you’ve probably realized many questions were posted but remain unanswered. Keyword – Jeopardy! Each question is at the same time an answer to the preceding problem. It’s also an invitation for you to explore Blazor topics. You might have even googled at least one, while reading. Each question will work as a key phrase in your search engine of choice. Developer’s attempt at “fun”.
Next up – architectural patterns! We’ll analyze the most common architectural patterns and how they apply to Blazor projects. We will also take a look at Blazor specific patterns, like BAMStack.
See you then!
More from Blazor Series