Hacker News new | past | comments | ask | show | jobs | submit login

In my previous job, I was on a team using Vue.js for the frontend and ASP.NET Core for the backend. I quickly got tired of the internal plumbing, package management, build configuration, and all the other things not related to the actual functionality of the app that Vue (v2) required at the time. So, when I started my own company last year, I quickly jumped on Blazor Server, which has been an absolute joy from a developer productivity perspective.

You can build really rich interactive experiences in Blazor at a fraction of the time required to build the same thing with the standard JavaScript SPA architecture. However, now that we have many customers using the application in production, we're starting to see some of the not-so-pleasant side of Blazor Server. When experiencing a lot of requests, the experience is degraded for all users of the app. In addition, it's not very good at re-establishing the WebSocket connection if it fails, giving a poor impression to the user. Though, I'm impressed with the latency—we're hosted in Europe and have customers in New Zealand who use the app without any latency issues whatsoever.

I'm excited about the auto-rendering mode, which looks pretty straightforward. I don't really buy the author's argument that it introduces an extra layer of complexity—we're still light years away from the complexity that a modern JavaScript SPA involves. For small teams with just a couple of full-stack developers, Blazor is still one of the best and most productive stacks, in my opinion.




> However, now that we have many customers using the application in production, we're starting to see some of the not-so-pleasant side of Blazor Server. When experiencing a lot of requests, the experience is degraded for all users of the app. In addition, it's not very good at re-establishing the WebSocket connection if it fails, giving a poor impression to the user.

We've been using Blazor server for ~3 years now and have had similar experience. We only use it for internally-facing administration sites, and even then it's still quite annoying to hear team members complain about the inevitable reconnecting to website warning, even when everyone knows exactly why its happening.

This experience with using websockets to move state between client and server has pushed us away from the idea that the client could ever be made responsible for any meaningful amount of state. In our current stack, we return final server-side rendered HTML and handle multipart form posts. There are no more websockets in our stack. Everything is stateless HTTP interactions - the client only manages a session token.

SPA was a fun experiment, but I am completely over it. If you are trying to fix some weird UX quirk, reach for a little bit of javascript. Don't throw away everything else that works over something small. There was a time when I would have agreed that you need frameworks, but that time has long since passed.

In 2023, approaches like PHP feel more valid than ever. I know way more about what doesn't work than what does these days. If you want something like PHP but you don't know where to start, you should think really deeply about what PHP is actually doing and if your preferred programming language does not also have a similar string interpolation concept.


Isn't a Blazor application a giant blob of WASM/Javascript? I understand that Blazor is more designed for internal line-of-business applications that require porting to the web (and would otherwise be a .net application running on windows xp), but it seems pretty untenable to use it as a framework for the web.


Blazor - until .NET 8 - came in Blazor Server and Blazoe Webassembly variants.

Blazor Server renders the DOM at the server and sends it to the browser. The server also holds on to some state for each client - notably the "current DOM" - so that it can calculate diffs on changes and only send the diffs to the browser.

Blazor Webassembly does the rendering in Webassembly in the browser. The .NET stack runs in the browser. Here, the code renders and diffs in the browser and the the diffs are applied to the DOM as well.

This also means that the same components can run either server-side or client-side. They basically all end up computing DOM diffs and applying those diffs to the actual DOM. Pretty neat, actually.

Each model has it's pro and cons. Blazor Server initialized really quickly and relies on minimal Javascript in the browser. But it creates load and server affinity on the server. Blazor Webassembly offloads all rendering to the browser, but at the cost of an initial load of the code.

In .NET 8 these can now be blended, and a new "auto" mode allows a component to be initially server-side and then client-side when the webassembly code has downloaded.

In addition to that is now (.NET 8) also the static server side rendering (and "enhanced navigation") which you could say is server side components without the "circuit" server affinity and server state of each client. Static server side rendering has some limitations on how interactive they can be - i.e. changing the DOM.


"The server also holds on to some state for each client"

If this is how Blazor is architected. Then I have no interests in using this and really anyone doing any type of web development shouldn't bother with this. Internal apps eventually need to be used externally. This is a time bomb waiting to explode on the users and the developers.

I use VueJS with Asp.net Core with multi-page single load architecture. Meaning once a page is loaded all other data is loaded through ajax. But the app is made of multiple pages. Over 10 years of being a web developer has brought me to this setup. Client UI state should stay on the client. All other state should be saved to the server. All communication should be stateless.


> This is a time bomb waiting to explode on the users and the developers.

I'm just saying a lot of the target they are aiming to replace is VBA applications slapped on top of Access DBs, and Lovecraftian nightmares born out unholy fornication of Batch scripts and unintelligible spreadsheet formula.

I'm not saying your wrong, just pointing out that even if this is a ticking time bomb it's a ticking time bomb that is using conventional explosives replacing a cesium based nuclear time bomb that is already counting down the seconds.


It's how Blazor Server apps are architected. Blazor WebAssembly apps don't maintain client state in the server and can be load-balanced like normal.


Seems like server vs client would also come with a set of security tradeoffs.


It’s just moving the work that would be happening in the browser to the server. There is no reduction in security with either of these styles


It can be hosted by either WebAssembly or by the server (in which case the server will render the DOM and send diffs to the client over a WebSocket connection). Blazor Server probably isn't the best choice for a popular SaaS app, mainly because of its dependency on WebSocket connections and less-than-perfect reconnection logic.

I'm optimistic about the auto-rendering mode, which will serve the app via Blazor Server (using a WebSocket connection) the first time the user hits the app. It will download the WebAssembly DLLs in the background so that the next time the user comes by, they will get the WebAssembly-hosted version. It's an interesting mix combining the best of both worlds (hopefully).


As a backend dev, I love the technology. The problem is that you have to choose between a not-so-scalable solution (Server, signalR) or a minimum 2mb initial payload (WASM) that can easily go to 5mb.

Interested on how many concurrent users you have for Server to be a problem. Can you elaborate more on your performance issues?


I may have made a mistake in designing the architecture of our app. Since we're a small team, I opted for a big ol' monolith, hosting our APIs on the same server as our Blazor Server app. We normally serve a few hundreds requests per second on our APIs, which is totally fine. However, sometimes we got some spikes up to thousands of requests per second, which has the unfortunate consequence that our Blazor Server app becomes laggy and starts to drop WebSocket connections frequently. So, now, we are in the process of moving our API controllers to another project, which will be hosted on a separate server.


Sounds like you did everything right then. Started off simple, now your business is taking off, failures aren't catastrophic (they're grey, not black, from what it sounds like) and splitting out a component shouldn't be too hard, so you'll be ready for more scale soon. All while maintaining the business!


.NET 8 solves that exact problem as far as I can see. You can opt into auto mode and it uses server side Blazor until the client downloads all assets, then in subsequent visits it uses the WASM runtime. Seems to be a good compromise.


Is 5MB a real problems? Theoretically it may look big, but I have seen many websites much bigger, not to mention all video/image we download are already skewing download by a lot. Considering runtime is cached for long time, I don't see a real blocker. First page render would be an issue but SSR solves that.


> Is 5MB a real problems?

Well if you want to make small fast loading html pages with a minimal js library, and end up at a few hundred KB that you can understand, profile and optimize, then that is impossible with blazor. So it's a very real problem.

If you want 5mb blobs and do not care about what is going on inside, how to optimize or reduce the memory and bandwidth usage, then it's not a problem, works just as well as the websites you have seen, with 200 node dependencies.


On a phone, 5MB it not ideal. On a corporate desktop, not an issue.


As someone in New Zealand that's crazy. The ping to Europe is terrible. To the point that video calls to the UK are painful.


I regularly have video calls from the UK to NZ with no issues at all. Might be your provider.


> I quickly got tired of the internal plumbing, package management, build configuration, and all the other things not related to the actual functionality of the app that Vue (v2) required at the time.

I don’t understand this. I’ve used v2 since before release and it’s never been anything more than an initial setup of 5m and then build your app?


Man, well done- how do you just start a company and instantly the biggest issue becomes having too many customers?


I share your perspective. It is the most productive environment I have seen in many years. Blazor WASM for internal company applications, PWA or Blazor Hybrid (basically Cordova/Electron Shell just with C#) is just awesome.

I share the article's fear of overloading the technology, but do not see it overall that negative.


In my experience, long polling is more stable and you can enable transfer compression. Maybe it would be good in Blazor to disable the persistent connection completely, having only requests and responses. Often we just want to call a backend method and update the view in response.


> In my previous job, I was on a team using Vue.js for the frontend and ASP.NET Core for the backend. I quickly got tired of the internal plumbing, package management, build configuration, and all the other things not related to the actual functionality of the app that Vue (v2) required at the time.

Oh, hey, I have something relevant to say about this setup. Currently I'm bootstrapping a platform with .NET Core on the back end and Vue 3 on the front end.

In short:

  - .NET is one of those boring workhorse choices, like Java - it's pretty stable, the performance is good, the type system is decent, IDEs are as good as it gets (Rider, VS), can run on Windows or Linux with no issues, there is an ecosystem that feels very coherent (more focus on ASP.NET than something like Spring in Java, because there's fragmentation around that, Dropwizard, Quarkus, VertX and so on)
  - Vue feels really nice to work with, the Composition API feels simpler than React, the developer ergonomics are fine, the documentation is nice, packages like Pinia, VueUse and VueRequest keep things simple, in addition to something like PrimeVue giving lots of UI components that you can use to iterate out of the box
  - however, while I think that the SPA approach can be nice to keep the front end separate from whatever technology you use on the back end, it comes at a cost of duplicating your data model and the interfaces between them (REST endpoint and client, for example), in addition to needing to think about how to deploy it all (separate domains vs context paths on the same domain, CSP, CORS etc.), though it's mostly doable
  - I did definitely run into problems with Vue not being the single most popular choice out there, for example I wanted to integrate Mapbox maps and the VueMapbox package is for Vue 2 only, whereas Vue 3 Mapbox GL breaks when you try to integrate it with mapbox-gl-directions. Eventually I switched over to Vue Map (Leaflet based) with leaflet-control-geocoder and leaflet-routing-machine but even those tended to break, because adding markers for a calculated route makes the map break when you zoom in/out, due to it losing a reference to the map JS object; in the end I just used patch-package to fix a few lines of code that didn't work in the offending packages instead of forking/building them myself, but that's a bit of a dirty hack
In short, I think that .NET is pretty good, Vue is pretty good, but the JS ecosystem feels like it works well only sometimes, even for reasonably popular solutions. On that note, I'm all for trying out things like Blazor, but then again my past experiences with Java and something like JSP/JSF/PrimeFaces/Vaadin have soured my perspective a bit (which is also why I prefer to keep the front end decoupled from the back end as much as possible, sometimes to my own dismay).

Honestly, it sometimes feels like picking anything that's not React is shooting yourself in the foot because everyone's building their libraries/packages/integrations for React. At the same time, I don't really enjoy React much at all.


I spent a decade with C# and .Net and even in its current form which is easily the best it’s ever been I vastly prefer to work with Typescript.

Yes, you do need to set up some rather strong governance around it for it to work for multiple teams, but you should really be doing that with any technology, and once you do, it’s just excellent. Part of the reason for this is that it’s basically designed from the ground up to require that you build and maintain “template” projects, have strong linting, testing and pipeline governance, so there is a lot of freedom to make it work easily for your organisation exactly the way you want it to. Typescript is obviously not alone in this, but it’s far less opinionated than something like .Net.

The main reason is that .Net always becomes burdensome once you start using it’s included batteries. This isn’t really an issue with C# as much at it is an issue with it’s libraries. Take OData and Entity Framework as an example, the .Net magic behind them sort of share the same model builder, but they do so differently. What this means is that a lot of the cool OData features like patch doesn’t actually work with EF, meaning you’ll either have to rewrite a lot of the model builder (don’t) or have to work around it. .Net has always sort of been like that. It variates between being 50-90% “done” but it never really gets there until it moves on. Like EF, much of the EF 7 road map isn’t implemented yet, but here we are, moving on to EF8.

I think for a lot of use cases it’s a wonderful technology, and Blazor will probably be awesome until Microsoft moves on, but at least around here, it’s also a technology that doesn’t really see adoption in anything but small-midsized companies, and in my opinion, .Net is part of what hinders growth. Obviously not a huge contributor, but once you step out of where it excels, you’re just going to have to fight .Net so much harder than you will with Typescript. Which is sort of interesting considering they are both Microsoft products which align more and more. That being said, it’s not like it’s bad either.


Batteries are included, but you aren't forced to use them.


Previously from this account: https://news.ycombinator.com/item?id=38228674

The tldr of both the previous and this posts is OData being bad yet the author extends his grievances regarding it to the entirety of ecosystem.


It seems a little disingenuous of you not to mention how I never hide the fact that it's an issue with the batteries. I'd also say that considering how great OData's patch is with the modelbuilder it's actually EF that's being bad in this case.

You could also point back to other posts like this one: https://news.ycombinator.com/item?id=37538333&p=3#37541652

Where I also point out other, similar issues with other parts of the .Net batteries.


If you are having issues with EF Core, maybe it's not the tool's fault?


I enjoyed using ServiceStack. Write your data model in the C# API, run a tiny CLI command and it spits out Typescript definitions to match your data model.

https://docs.servicestack.net/typescript-add-servicestack-re...


TypeLite used to offer something similar, but it's somewhat dead nowadays.

OpenAPI client generators are probably what's popular today.


Yep. For frontend use, I think https://www.npmjs.com/package/openapi-typescript is the most widely-used/well-regarded, though https://www.npmjs.com/package/orval seems to me to have some nicer features like react-query support.

There are other options too, I'd just stay away from "_the_ openapi generator" (https://openapi-generator.tech/) which does a pretty poor job IMO.

Disclaimer: I'm the founder of a company doing SDKs commercially, but we don't focus on the frontend right now, and our free plan is still in beta.


> however, while I think that the SPA approach can be nice to keep the front end separate from whatever technology you use on the back end, it comes at a cost of duplicating your data model and the interfaces between them

Can you elaborate on this? I'm not sure I get it, because once you have your view model in asp.net, it seems like it should be easy to derive a JS/TS model from it using various techniques (reflection, source generators, etc.).


> it comes at a cost of duplicating your data model and the interfaces between them

Not the case if you use graphql.




Join us for AI Startup School this June 16-17 in San Francisco!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: