Hacker News new | ask | show | jobs
by matt2000 3521 days ago
I'm a little confused about the benefits of server side rendering. I thought the point of these js UI frameworks was to make the client do a bunch of the work? Can anyone give me some of the upsides? Thanks!
7 comments

Two simple practical benefits: (1) Performance for first page load. (2) SEO.

Also because of network latency sometimes it's faster to just reload the whole page than to send a few async requests and wait for them to return while the user sits there wondering what's going on.

classic SPA: (client request) -> (retrieve empty divs + js) -> (js kicks off) -> (API results used to fill initial page content) -> (further page interaction calls APIs to mutate client side page)

SSR: (client request) -> (server retrieves empty divs + js, API results used to fill initial page content) -> (fully rendered first page view + js delivered to client) -> (further page interaction calls APIs to mutate client side page)

this sounds great, but isnt the point of a js web app that the data resides or are cached on the client !? Making it possible to use offline. And have real time push via websocket when online !? Server side rendering frameworks are as old as it gets.
The point of a js web app is that you can run it in a web browser. Hammers and nails are even older than server side rendering, yet somehow they still function perfectly.
There are advantages to not coupling the client and the server. Like for example e-mail and IRC-chat. You can have a browser client, but also a native mobile app client, bot running against the same server API. Decoupled software almost always means more productivity.

Hammers and nails equivalent is cgi/perl/php/asp and they still do a fine job. You can use the screw machine to manually punch down screws, but then why not use the hammer and nails instead, as you do not see the advantage of the screw machine.

Yeah those would just be separate endpoints/requests. text/html vs application/json. Instead of serving a static html file that bootstraps your react app, you're serving a rendered component.

Not really any different from building say a PHP app that serves an API to a mobile app.

If the user has JavaScript turned off, the whole point of a JavaScript app is lost. You could just render all the HTML on the server like a PHP app, witch would also make Reac pointless.
So from what I understand, the benefit of these single-page-app frameworks is not that it makes the client do all the work, but that the user experience is more fluid (aka no full page loading and blinking). Doing 'work' on the server side will always be faster resource wise. This project tries to straddle both benefits by injecting server-rendered sub-components into a single page app. P cool if you ask me!

Keep reading past: "## Automatic server rendering and code splitting" & "## Anticipation is the key to performance"

Each sub-component is loaded dynamically which speeds up the initial load time but still allows for the 'flow' of single page apps.

- "For www.zeit.co we've implemented a technique on top of Next.js that brings us the best of both worlds: every single <Link /> tag pre-fetches the component's JSON representation on the background, via a ServiceWorker."

server side rendering only on the first load / if the client has disabled js. If the client has js enabled, after the first load, the app works as a js spa
One benefit is less roundtrips to actually provide meaningful content to the user.

As another comment noted, a typical SPA just delivers a bunch of script, link and empty div tags to be populated after JS loads and runs on the client. With SSR you can at least provide some meaningful content for the user to experience while the rest of the JS loads and improves the existing experience instead of providing the entire experience.

Server-side rendering generally has quite a few upsides:

* Simplicity. You don't need a fancy bunch of tools to cross-compile things, or any big frameworks, because a bunch of problems (browser compatibility especially) disappear. No more random people's browsers. You control every variable, and you can far more easily accurately test the end result.

* Shared data between requests. You can easily cache requests to backend services for multiple users, or even cache the entire rendered outputs of pages or parts of pages. Instead of every one of your users hitting a backend service from their browser and waiting for the result, you can hit it once every X, and then every other page load becomes just a cache read. In many simple cases you can have dynamically generated page content that's served up and readable after a single cache read, and update the cache totally async on the server too. Super fast.

* Data transfer, sometimes. If your end page is small but you use a lot of JS to render it, and your users load new pages more often than they reload content inside an already open page, then you might well end up transferring less data with a server-side approach (although this is very case specific).

* Page rendering times. If you use JS frameworks badly browers will really struggle, especially on mobile. Even with React you can really shoot yourself in the foot: https://github.com/reddit/reddit-mobile/issues/247. Obviously you shouldn't use JS frameworks badly, but people do. Static HTML + CSS reliable renders very very fast, everywhere.

* SEO. Google now has a degree of ability to run JavaScript (not unlimited, but fairly good), but nobody else seems to. Google is about 80% of US search traffic, so if any content you render client-side only will get about 20% less search traffic than it would otherwise.

* Accessibility. Some screen reading tools etc aren't great at JavaScript (although this is improving). More generally all sorts of other tools (site scrapers, sentiment analysis bots, whatever) have to put in way more effort to read your content.

* Network resilience - if you serve up only half an HTML page, or a couple of your external resources get dropped, your end user probably gets something sensible-ish. If you drop a JS file you depend on for rendering, it's all over. Offline with service workers is a good argument for progressive enhancement on top of this though: JS can also improve later network resilience drastically.

That's server-side rendering generally - the comparison gets more complicated and you lose some of this (simplicity especially) if you do isomorphic rendering (as here I think), where you render the page on the server and the client too.

The second point "Shared data between requests" would actually turn into a negative when it comes to dynamic web apps; if you had to re-render a component in realtime and send the HTML for that component over the wire for every permutation and change of data (which will be different for each user), caching would be futile. Also, this will basically move cache consumption from the client to the server; which is worse for the company which has to pay for hosting.

Performance-wise, full server-side rendering is a huge step back. For dynamic web apps, next.js is going to drive up hosting costs massively and open you up to DDoS attacks because of server-side cache issues. I suppose it's OK for static websites.

Also, if the JS fails to run on the client (which you have no control over, and which is pretty common), the page still loads.
> and which is pretty common

s/common/uncommon

Happens all the time if you're travelling and your mobile data connection is going in and out.
i'm not sure i follow your logic. how does a poor data connection affect js execution?

if you have to do additional template fetching via follow-up async requests, sure. but if you serve the js & js-parsed/executed template in the initial request, then the only difference would be a synchronous reflow/paint for js (white page flash) vs streamed/incremental reflow/repaint.

If you can barely get 1 request through, it might take a long time before the JS will load and run, as it has to load completely before running at all.
A poor data connection would affect the js download, not the execution per se.
noscript is not uncommon
maybe amongst HN (i swear by uMatrix & uBlock Origin), but the general public prefers their favorite websites not to be largely broken.

completely disabling scripting [rather that just disabling third-party script injection] is not a pleasant experience, even for the technical crowd. i already reluctantly have to whitelist CDNs which can track me across the internet.

We will eventually go full server rendering and just stream every frame to a thin client. We have good enough network now with gbe consumer bandwith and less then 1ms latency up to 50km. But we need more powerful, smaller and cheaper servers.
>We will eventually go full server rendering and just stream every frame to a thin client.

You just described every single non-SPA...

No, I mean more like a remote desktop experience.
How does that make economical sense?

I can pay to render everything for my user, essentially streaming their webpage to them. Or for the potential cost of a slightly slower page load I can offset the cost of all that rendering to their xGHz multi core CPU that's likely sitting idle.

Not to mention the cacheability of the data.

Because bloating your client's experience has negative effects too: lower battery life, lower performance, higher memory usage, ...
It would make digital rights management (DRM) easier. Companies already spend a lot of money on DRM. There are already services today that lets you use a remote desktop for computer-aided design (CAD) work or gaming. But as you said, it's not economical yet.
Latency is certainly not 1 ms for a video frame in desktop resolution. It also means lower visual quality due to the fact that video compression would be needed to make it even slightly possible. Also, how many people actually have a GbE connection to the internet?
The 1ms is network overhead, witch is nothing considering how long it takes for the image to render on the screen. The CPU and the GPU could be several miles apart.
> The 1ms is network overhead, witch is nothing considering how long it takes for the image to render on the screen.

Yes, latency for a single bit of payload to ever hit the client. The rest of the data then needs to be transferred as well. Transferring that amount of data constantly would be terrible with regards to battery life.

> The CPU and the GPU could be several miles apart.

How exactly? Would you send draw commands over the internet?

More data sent via carriers means they will be able to negotiate better deals and peering. So when 10Gbe hits the consumer market, they will let their users have 10Gbe downstream bandwidth, like a HDMI cable. With some compression you could stream 60 fps + sound. Sure it would use a lot of power, but the usage would foremost not be mobile devices, more like TV's for gaming, and workstations for other programs, BC to PC full circle. You could probably do a lot of optimizations like using a vector format, to drastically decrease bandwidth. I do not know exacly how it can be implemented technically, please give me break ... Some times things can be turned upside down and it's really hard to change your way of thinking, like HDDs gets faster then RAM or networks is almost as fast as internal buses. Not saying it is like that today, but it might be soon and it will be hard to break out of old design patterns.