I didn't say there are no use cases for a SPA, what I'm arguing is that in the vast majority of cases it's not a good option.

What constitutes a SPA? Essentially it is a JS application that handles all route changes and in consequence also has to handle application logic, state, etc.

To be able to achieve that kind of functionality development becomes much more complex. Not only you now get all the architectural nuances of making an app, which your typical JS dev doesn't understand, but the dev workflow becomes convoluted for a number of reasons:

1. Not all browsers support the same language features and APIs which introduces the need of using transpilers like Babel or Traceur.

2. JavaScript is objectively a poor language for complex projects hence the success of alternatives like TypeScript.

3. The JavaScript standard library does not live up to the necessities of the modern front end developer which introduces the need of using and managing more dependencies. For example, after all these years there is still no native reactivity.

For these reasons we now have to use bundlers like Webpack, NPM dependencies, and a very long etcetera. Plus a continuously changing dev landscape (see React hooks for example).

It is still challenging to make an accessible SPA. Common functionalities likes control+click on a link have to be re-implemented.

Of course sending all this functionality to the client can have a serious cost in size and CPU. It's not as big in leaner frameworks/libs like Svelte but it's always there.

The initial bytes can be mitigated by using something like Webpack chunks, but again this introduces more dev complexity.

Finally, in the vast majority of cases (if not all) SPAs also render the content. This requires developing an API (GraphQL, REST, etc) which introduces another layer of complexity vs doing the rendering in the server. In some cases this is necessary as there can be various clients, but not always.

IMO all these drawbacks make sense when the SPA model is justified and there is a need for sophisticated functionalities. Gmail is the perfect example. Soundcloud is another good candidate since audio needs to keep playing at all times.

So usually the arguments in favor of an SPA are that the UX is better or that after a number of clicks the user receives less bytes compared to receiving markup.

I think that the UX benefits of a SPA are exaggerated for common use cases (e-commerce, CRUD admins, enterprise apps, marketing websites, etc). Amazon, Ebay, Wikipedia, are not SPAs and they are still getting millions of visits every day and probably growing.

As for getting the data in JSON or WebSockets vs getting HTML, yes, after a number of clicks there are some bytes savings but after having paid a high cost in initial bytes and CPU cycles. This argument could make sense in very particular use cases, but I don't think it can be applied as a general argument on all websites. It makes sense for gmail, since there is a lot of clicking around and changing views, but that's not a concern for the vast majority of websites.

I should probably write an article about this since I've left out some points and haven't gone with much depth into others... but I hope this comment conveys my position.