A single page app is just this: a web page that doesn't ever reload the page or reload scripts. It doesn't matter how much content the initial page had on it, and it certainly doesn't mean that you send an empty body tag. The history APIs even let the back button and URL bar behave exactly as the user expects them to, but without a single round trip if you already have the data and resources.
While it's certainly true that the first page may load slower, and you'll load a few scripts as well, you never need to reload those again. Frameworks like Angular encourage you to use a "service" mindset that capitalizes on this property.
The longer you use a single page app, the fewer round trips you will have. If you ask me, your communication should only be for raw materials (scripts, templates) that you won't need to validate or request again during the current session, and raw data (json). This is more loosely coupled, more cacheable at all the different levels, and more scalable in large part due to the decoupling.
Once the initial view loads, I totally agree that you should intelligently precache all your resources and data asynchronously in the background to usher in the era of near zero-latency user interactions. Preferably, you do this in an order based off of historical behavior/navigation profiling to best use that time/bandwidth you have before the next click.
I get the impression articles similar to this one that there was once a similar mindset surrounding mainframes and dumb terminals. The future is decentralized, web included.
I think people have different use cases that they aggregate under "web application". If you are building a desktop replacement application then I can see that initial load might not be such a big deal but if you are building a less complex application like the Twitter UI then server side rendering makes more sense. It's all context specific in the end. To hard to make general claims.
Actually, I think twitter is a prime candidate for a JSON-driven client-rendered application. It's a pretty static shell, with a static tweet template iterated over large amounts of tweet data.
You could completely eliminate a huge number of round trips by just getting tweet data and user data after the initial pageload. The user data is quite cacheable and you could create a single endpoint that allows the user to precache the required user data (display name, photo url, id, etc) for everyone he follows in one round trip.
They moved away from client-side rendering. Quoting:
There are a variety of options for improving the performance of our JavaScript, but we wanted to do even better. We took the execution of JavaScript completely out of our render path. By rendering our page content on the server and deferring all JavaScript execution until well after that content has been rendered, we’ve dropped the time to first Tweet to one-fifth of what it was.
I'm not a Twitter historian, so I may be wrong, but I'd be willing to bet that their client side rendering allowed them to scale the way they did. When your customers' computers are doing half the work or more, adding a customer costs you half as much or less.
Decentralized work is a bad thing. Instead of Mozilla/W3C solving some problem for everyone, we get every website coming up with their own clever solutions for nearly everything. (Also, thousands of clients re-doing the work that could be done once and served from cache.)
Also, single-page apps increased reliance of the entire web on the handful of CDNs and framework providers.
> every website coming up with their own clever solutions
I take it you're not a fan of open source, then? :-D I don't think the problem you describe has anything to do with decentralization, though. You can have people thinking they know better than the rest of the world writing COBOL for AS400s.
Further, I don't think you can soundly argue that decentralization is a bad thing. For one, it's the the only way you can scale horizontally whether that's done on the server side or by deferring appropriate work to be done on the client side. For another thing, as OP's article states, round trip time has a theoretical lower bound. The only way to improve performance past some a point is to distribute closer to your users.
I 100% agree by the way that if it can be cached it should be. I don't, however, think that necessarily extends to a SPA. JSON is just as cacheable as HTML if the interface is designed with proper REST semantics.
Open Source needs to be used first. Do you want to rely on websites implementing something like spell-checking? In your native language? I don't. I want common problems to be solved in the browser and I want to have some reasonable control over my browsing experience and some consistency - something SPAs actively undermine.
How are SPAs different from Flash? Sure, you have some remnants of standard HTML there, but with canvas, local storage and JS compilers, those two technologies look remarkably similar both in terms of advantages and problems. You get a blob of non-semantic, imperative code that does non-standard things.
The funny thing is, many of the stated advantages of SPAs can be easily implemented in document-based web apps. A lot of the repetitive info could easily be removed with proper caching, and it would be even more efficient with cacheable client-side includes. Not only it would be roughly as efficient, it would require much less work to implement.
While it's certainly true that the first page may load slower, and you'll load a few scripts as well, you never need to reload those again. Frameworks like Angular encourage you to use a "service" mindset that capitalizes on this property.
The longer you use a single page app, the fewer round trips you will have. If you ask me, your communication should only be for raw materials (scripts, templates) that you won't need to validate or request again during the current session, and raw data (json). This is more loosely coupled, more cacheable at all the different levels, and more scalable in large part due to the decoupling.
Once the initial view loads, I totally agree that you should intelligently precache all your resources and data asynchronously in the background to usher in the era of near zero-latency user interactions. Preferably, you do this in an order based off of historical behavior/navigation profiling to best use that time/bandwidth you have before the next click.
I get the impression articles similar to this one that there was once a similar mindset surrounding mainframes and dumb terminals. The future is decentralized, web included.