> What? No. Not at all. If you're behind a subpar network, your dynamic HTML web app does not load/refresh/update at all, and your users start to get frustrated because your crappy webpage is broken and fails to even do the most basic things.
>
> This is not the case with SPAs, and some of the most pressing problems they solve: perceived performance, resilience to faulty network connections, and overall improved UX.

That's the sales pitch but here's what actually happens for the vast majority of time: the user gets frustrated because after 5 minutes the SPA finishes failing to load and all they have a blank page or, if it's a site they visit so frequently that all of its dependencies tree are still in the browser's cache, they get the UI shell but nothing works. As a bonus, the assumption that the megabytes of JavaScript would manage state often means that core web functionality like the back button or reloading do not work so while a CRUD user would be able to hit reload and get the expected result as soon as their network connection improves, the SPA user will have to start over from the beginning.

It is technically possible to build things which work offline but in the real world that doesn't work for most applications for a number of reasons:

1. The app depends on things which need to make network requests — you can give a nicer error page but that's not going to make your users happy.

2. The developers ship updates often enough that cached versions aren't current — e.g. you might have all 50MB of dependencies in the cache but if the user got the HTML referencing different URLs, that doesn't matter.

3. The developers forgot to test that they allow long-term caching or serve-stale on their assets.

4. There's a big difference between being completely offline where the interface status shows down and high latency / packet loss. The most frustrating experience for the users are the latter because things act like they're going to work and if they were doing an activity which changes state it might not be clear whether something succeeded or not. The offline API doesn't work for that and it's almost certain that your SPA doesn't really handle it because:

5. Statistically nobody tests in those degraded conditions so they end up with the Twitter-style SPA where it loads the core of the UI structure but then nothing renders. This is better than a server timeout page only in that it allows you to try to convince the user to be less frustrated.

The reason why this is almost always better for server-side rendering comes down to the increased client footprint of an SPA. With an SPA you're depending on an enormous amount of code to load and run before the user sees anything and there's a lot more that can go wrong in ways you didn't handle, which is why it's so common to learn something is an SPA when you get a “successful” blank page. Servers certainly can have problems but most of the moving parts are under your control so you have better visibility and control, and there's no better way to handle degraded conditions than to depend on them less. If the network is slow, trimming your transfer by 1-2 orders of magnitude is going to do more than almost anything else to improve the user experience.