6 ms·
I pretty strongly disagree with this. The distinct advantage of an SPA is that, done correctly, cached data lets you render pages instantly. Who CARES if the
by horsawlarway 5y ago
I pretty strongly disagree with this.
The distinct advantage of an SPA is that, done correctly, cached data lets you render pages instantly.
Who CARES if the SPA had to make 3xRTT in the background, if it can serve the next page up instantly because that data is already present and cached, it's a huge win.
The server rendered app will ALWAYS have to wait at least 1xRTT for every new render. The SPA does not.
Still doesn't make an SPA the right fit for everything, but on bad networks, we get incredibly improvements in performance by rendering from cache, and occasionally handling cache updates in the background. User's fucking love it compared to waiting 2-5 seconds for every page load, even if they were JUST on the page a second ago.
- midrus 5y ago> done correctly Big assumption. This is what the whole discussion is about. Doing "correctly" an SPA is incredibly expensive. I can also assure you that when an MVC application is done correctly you can have an equally good user experience. > The server rendered app will ALWAYS have to wait at least 1xRTT for every new render. The SPA does not. This is an outdated idea of how server rendered apps work. See Unpoly, HTMX, LiveWire, Hotwire, etc. I'm personally using Livewire. I make server request in only 2 situations. 1) When going to different pages (I'd need that anyway with an SPA given I need "SSR") and 2) When I'd need to write or read data from the server, which with an SPA would mean I need an API call anyway. Every other interaction is done with Alpine, 100% client side.
- hinkley 5y agoUnless their cache is cold and then they navigate back before your first render completes. Often we are not the sole source of a piece of information and first load time counts.
- horsawlarway 5y ago> Unless their cache is cold and then they navigate back before your first render completes. This doesn't matter. It's an SPA - my js context hasn't been wiped because I'm not letting the back button eat the whole thing and start over. I just complete the request and store in cache either way, and next time they hit it, it will be there. > Often we are not the sole source of a piece of information and first load time counts. Sure - caching is hard (full stop - it's really hard). But I think if you actually consider most applications, there's not really much difference between an SPA rendering from cache and a server-side page that a user hasn't refreshed in a bit. Basically - it's not going to solve all your problems, but in my experience developers really underestimate how much usage is "read only" and a cache works fine.
- hinkley 5y agoIt doesn’t matter‽ SPAS push giant gobs of logic and CSS ahead of the Time To Interaction and cross their fingers that nobody will notice because it’s not supposed to happen the next time due to magical cache thinking. People have been ignoring actual research on caches for the entire time SPAs have been around. First time visitors have this as their first time visit. Occasional visitors show up after the last deploy, or like and enthusiastic web users get evicted between loads. And then don’t convert because your site is “always slow”. P95 statistics don’t tell you if 5% of your users are having a bad experience. Or if new users are massively over represented in the P95 time. You are flying blind and shouting for other people to follow you.
- zozbot234 5y agoTo be fair, there are SPA frameworks that try to minimize the amount of logic that's shipped to the client, Svelte is an example, which should be as lean and efficient as any hand-coded JS. It's more of a side effect of what frameworks you use than SPA per se.
- hinkley 5y agoIt's still a specialty sub-discipline though. Getting the base size down is a wonderful goal for a framework. But for the behavior the company is adding, there are both diminishing returns and a lot of surface area for bugs.
- horsawlarway 5y agoLook - I understand that I'm making a tradeoff here, and I'm very clear that not all sites are the right fit for an SPA. But yes - I explicitly handle offline-only use cases, and god-damned terrible connections (think <1kb/s). In these situations, users are going to wait a long time for the first load either way. They call in excited as all get out when they realize they only have to wait once with my application, and not once every page load. It's the difference between having a chance to grab a coffee at the start of the day, vs pulling your fucking hair out all day long.
- kevinmcconnell 5y ago> The server rendered app will ALWAYS have to wait at least 1xRTT for every new render. The SPA does not. Not necessarily. I think you're conflating caching/fetching and rendering here. You can cache rendered views in the same way you'd cache the data for those views. Turbo does this, for example. When you navigate to a cached page it will display the page from the cache first, then make a request to update the cache in the background. So it's similar to what you describe, but with server-rendered content.
- horsawlarway 5y agoTurbo is making your site an SPA, and hiding the implementation details from you That's not what the article was about (it was very clearly advocating for the standard browser flow)
- tomnipotent 5y ago> You can cache rendered views Sort of. There's been no shortage of vulnerabilities where user data has been exposed when an authenticated users request was cached and re-used for subsequent users. It's been my experience that most SSR apps disable caching for authenticated users, or rely on more explicit control of components for partial caching where possible.
- zozbot234 5y agoPreloading is a browser-native feature, you don't need a SPA for that. And just as often you can't know in advance what data will be requested by the user.
- horsawlarway 5y ago> And just as often you can't know in advance what data will be requested by the user. This is a cop-out. Storage is insanely cheap, and abundantly available on most machines. Plus the browsers will usually give it to you. Can I know precisely what series of pages this user might hit? Nope. Can I load ALL the data this user might need to read? Probably.
- onaworkcomputer 5y ago> Can I load ALL the data this user might need to read? Probably. You can do that with HTTP/2 server push on a multi-page app, too. The main difference is that with an SPA, you get to reinvent it all yourself.
- horsawlarway 5y agoYeah - there's a trade off here. Server push gets you closer with a traditional app, but it doesn't really solve the problem (or rather - yes, you get to reinvent it yourself, but you can do it better, with the specific context of your app) Basically - My argument is that developers tend to treat SPAs the same as "the website" but with a bigger js framework. And that's the wrong mindset. Instead, you should think of the first load as an install of a native application. You want to push absolutely everything, not just the next couple of resources you might need (like imgs/css). Ideally you push the current page first, and do the rest in the background while the user can interact with the current page, since you're almost never CPU bound on terrible connections anyways. You'll get one additional load at login (because now I'm pushing all relevant user data), but after that... basically everything is rendered from cache (including optimistic cache updates based on what the user might be adding/updating). After that... unless you log out or have cache evicted, you're going to see immediate response times, even while offline. --- This isn't easy, and most teams don't bother, so if the comment is "If you're treating an SPA like a traditional page - don't bother" then I tend to agree. but an SPA genuinely opens up options for bad connections that otherwise just don't exist (or are so bad people won't use them)
- freedomben 5y agoHave you tried to use a heavily SPAed site from a slow, distant (high latency), or metered connection? A SPA that works and feels great from a big city quickly becomes unbearable when internet access isn't as ideal. There are ways to handle this nicely, but maybe 5% of devs actually think about and test that, and no PM will allocate sprint time for it.
- gowld 5y agoHave you tried to use a site that reloads all the data on every click, from a slow, distant (high latency), or metered connection? Same problem.
- freedomben 5y agoOf course, and it's usually not as big of a problem because everything you need comes in the page render. With SPAs it's not uncommon to have to click 5 or buttons/menus and then wait for data to load, then click again, and more data. That said there are plenty of SSR sites that are terrible too. It's not the technology that's at fault, but SPAs and common dev patterns in the community definitely enable and encourage making lots of small requests.
- tomnipotent 5y ago> have to click 5 or buttons/menus and then wait for data to load, then click again, and more data. How is that any different from SSR? Waiting for a full page reload is fine, but incremental loading is not?
- int_19h 5y agoWorse yet, with a traditional web app, you are in control of loading the page - or stopping the load, for that matter. With an SPA, it does all those requests in the background. Many apps fail silently (as in, don't refresh) if request to the backend fails.
- efdee 5y agoIn case of slow internet, SPAs are much easier to make responsive than an SSR application.
- giantrobot 5y ago> Who CARES if the SPA had to make 3xRTT in the background, if it can serve the next page up instantly because that data is already present and cached, it's a huge win. The data is never in the cache. It is for a developer because they forget to clear their caches when testing. For most users the data will not be cached unless they're sitting on the SPA all day. So when the user doesn't have data cached that 3xRTT on their spotty 4G signal the SPA pattern is of no help. Not everyone is sitting still on great WiFi. Someone's cellular reception can go from great to unusable just walking down the street.
- horsawlarway 5y ago>The data is never in the cache. Then you have a shitty app. Between localstorage and indexdb - unless you're literally out of disk and having storage being evicted, then if you've loaded my app once (and I mean once, not once this browser session) then I have data in cache. Basically - don't blame SPAs, blame developers for assuming that the same "request the data every page view" paradigm is still in play. It's not, and storage is insanely cheap.
- acdha 5y ago> Then you have a shitty app. This feels a lot like you're making a “No True Scotsman” argument. The behaviour you're saying doesn't / shouldn't happen has been the defining characteristic of SPAs since the beginning and it's still immediately visible on most of them as soon as you have a less than perfect high-speed internet connection. If statistically nobody except the Wordle developer can make something which handles crappy WiFi the problem requires more than just saying someone is a bad developer.
- onaworkcomputer 5y ago> The distinct advantage of an SPA is that, done correctly, cached data lets you render pages instantly. Yeah, but full page caching is a thing, and in my experience, teams writing traditional server-rendered pages are much more aggressive in their use of response caching than are teams writing JSON APIs. Honestly, a Rails/Django/Laravel app with smart caching headers and a Varnish instance in front feels more reliably instantaneous than the bespoke caching solutions each SPA seems to invent for itself.
- Tabular-Iceberg 5y agoHow does that work if a user is logged in and private data is visible on the page? I’m thinking of building something that only renders public data on the server, and then later gets that which pertains to individuals through an API. But I don’t want to spend more time on a lot of complicated plumbing than on core functionality in my application. A SPA seems like the path of least resistance here, since all you have to do is put the appropriate cache control headers on your API endpoints, and let the browser abstract it away for you. I know programmers like to build bespoke caching solutions, been there, done that, but you don’t actually need to. My biggest gripe with SPAs is the overhead of building and maintaining an API for everything, but GraphQL takes away a lot of that pain.
- onaworkcomputer 5y agoI've seen a lot of projects that use a full response cache to capture a view with holes where user-specific information would go and then fill in those holes with some client side JS. I wouldn't call those SPAs, though. But I'd say it's more common to just use "private" cache headers in this case for any page that differs for logged in vs unauthenticated users. The user's browser will still serve as a full page cache, but shared caches will ignore those pages.
- 411111111111111 5y agoGraphQL is a protocol, as such it cannot take away the pain of creating a backend for your frontend. There are tools which make the creation of the backend painless and utilize GraphQL for sure (i.e hasura), but claiming that GraphQL solved that issue is nonsensical, because writing the GraphQL API is generally way more annoying then the equivalent rest API is