We have pretty much always had iframes and form posts that can be targeted to submit to hidden iframes that JS can read, so XMLHttpRequest is easy to polyfill.
We used to use jQuery and globals or straight DOM manipulation. Or Backbone.js or just straight classes.
It has always been possible to make a SPA. And if you actually are able to download and cache most of the app upfront, it should be pretty quick. The question is, I suppose, how big is the SPA codebase and do newer browsers know how to cache identical codebases into their "entry points"?
The real draw of React and Vue, and more recently, Lit-Element (Google), is that they update the DOM in a smart efficient way, doing updates much more efficiently than you might could do without an intermediate layer.