This article misses the single most important reason to use SSR: single language applications are single build applications. Frontend builds are basically a requirement for any application with a UI. You're always going to have CSS, and some degree of user interaction for even the simplest website, which means JS/TS. One of the most important developments for frontend assets in the past decade is dependency managemen…
Sane dependency management is NuGet, not NPM. Sane build tooling is dotnet build, not npm run build (is this multithreaded/parallel yet?). Sane CI is achieved via dotnet package; then chucked into whatever CI workflow.
It just works. You don’t need to mess with it. It adds negligible overhead.
The DOM is inefficient — entire page loads are quicker than rendering changes in-page (accounting for latency, and using chromium’s Blink renderer). The box model is inane. JS is a horrible, cobbled together language (like Python) initially designed by a naive. I would sooner write my own 2D renderer in WebGL than deal with HTML/CSS/JS/Rendering pipelines.
In my many years of being a web$hit, I have always had to fight the frontend ecosystem to stop being daft.