> now you need to send all of the surrounding html over, when only a small table or form would need updating
No, you don't. For something like the upvote button on HN you can do an ajax call with a line of javascript. In the context of the conversation this is very far from bloated SPAs.
HN is a good example: each thread page consists mostly of comments. Reusing the same DOM across different pages would do very little.
Gmail is another: the default UI is a heavy SPA. The "plain html" mode is not. And it's faster.