
Operationalizing Node.js for Server Side Rendering (2018) - davidjnelson
https://medium.com/airbnb-engineering/operationalizing-node-js-for-server-side-rendering-c5ba718acfc9
======
jdlshore
This was a strange article for me to read. It starts out with a long
discussion of Node's "single-threaded compute / multi-threaded I/O" model as
if it were a problem for compute-bound applications. But multithreading
doesn't magically make compute-bound tasks go faster. Multiprocessing does,
but you can fork a Node server so it runs across multiple processors quite
easily.

(Keeps reading...) Ah, about halfway through the article they talk about
introducing multiprocessing using the `cluster` module. But then they say the
process is tied up until the request is fully received, bottle-necking the
process based on client speed, which is not how I understand Node to work at
all. Sure, the slow connection will tie up a socket and memory, so a buffering
proxy makes sense, but it shouldn't affect compute. Maybe it's a limitation of
`cluster`? My experience is with `worker-farm`.

Which brings me to the second oddity: CPUs are _fast_. What is Airbnb doing
that takes so much compute? Perhaps server-side React is slow? On my own,
admittedly low-traffic Node site, I use jade/pug for templating, and the
initial template compile step can be expensive. But then I cache the compiled
template and everything is too fast to care about thereafter.

I don't doubt that they had a problem, or how they fixed it, and I enjoyed
this deep dive. Nonetheless, their reasoning about the underlying causes don't
ring true for me.

~~~
cynicalreason
so, after reading the article, yeah, think he explained it a little bad.
basically what he's saying in a single node thread node's parallel model
doesn't magically fix compute requirements. that graphic of fn1 and fn2 and
compute is confusing.

personally never used clustering and the cluster module (we did that at
haproxy lvl with containerised individual node processes), but I think that's
exactly what he's saying, that the cluster module is the limitation
([https://nodejs.org/api/cluster.html](https://nodejs.org/api/cluster.html)).
not sure how they use it but it seems to imply requests being fully read in
the cluster PID than passed to the workers

------
azangru
Was hoping for a second there that they found the way not to include the
serialized state (as json sitting inside the script tags) in the body of the
html document (to make the page lighter), but no, that's not the case.

Anyway, it’s interesting how they separate the code for fetching data (making
it a responsibility of one server) from the code for rendering data (making it
a responsibility of another, Node-based, server). Which means that although
they re-use the code for components, the code for data fetching logic must get
duplicated.

~~~
cynicalreason
you don't NEED to include the serialized state in the body of the HTML, this
is the common practice, you can wait for the client to parse your js and then
make a separate request for the state data.

I don't get point 2, if they are to 'hydrate' the react renders in node with
data, they have to have a 'fetching' logic in there, the fact that it connects
to an 'API' instance makes no difference, the client could use the same
connection with same logic client side.

~~~
azangru
> I don't get point 2, if they are to 'hydrate' the react renders in node with
> data, they have to have a 'fetching' logic in there

The way I am understanding their blog post, they have a dedicated server
(let's call it server1) for api requests, and then a server for rendering
(let's call it server2). Server1 does all the fetching logic and then sends
the received and appropriately processed json to server2, which needs only to
use this data for rendering.

------
mywittyname
It took less time than I imagined to come full-circle.

------
lewisjoe
Anybody out there using
J2V8([https://github.com/eclipsesource/J2V8](https://github.com/eclipsesource/J2V8))
for such purposes?

------
z3t4
What are the pro et contra for react vs php for server rendering ? I thought
react was php for the frontend. So running it on the backend seem backwards.

~~~
azangru
> I thought react was php for the frontend.

Erm. In what way? Ubiquity? Code quality?

~~~
z3t4
Most people don't know what templates and MVC pattern means. But that's
basically what you do in PHP, maybe in a more simple form, but still.
Basically how all traditional web apps are built whether its Java perl or cgi.
React is pretty much the same, like all other web frameworks, but more
powerful as it can rerender parts of the view - instead of the whole view. But
if you use it server side I really see no benefit, as you would have to render
the whole view. Does this make any sense ?

~~~
azangru
If you are then re-using the same React code on the client side (and you
generally are), then of course it does. This is the enticement of "universal"
frameworks — you use the same code (perhaps with occasional slight
modifications here and there) to run on the server side and on the client
side. Imagine your Symfony, Django or Rails app that runs not only on your
server, but in your browser as well. That’s roughly the luxury that server-
side React (or Angular Universal, or Vue, etc.) gives you.

~~~
z3t4
Component reuse would be a selling point. But what about stateful components
that change colour or what not, do they still run on the client side? And what
about a todo-list like the one on the react start page, will it "magically"
use hidden forms and make http posts to update the server state ?

~~~
azangru
> what about stateful components that change colour or what not, do they still
> run on the client side

Yes :-)

Statefulness of a component is not useful for server-side rendering anyway,
because component state will only change on the client side. But yes, stateful
components work both client-side and server-side.

> And what about a todo-list like the one on the react start page, will it
> "magically" use hidden forms and make http posts to update the server state

I am not sure what you mean. Filling in and submitting a form only makes sense
on the client side. It can be pre-populated with data during server-side
rendering though. Naturally, http requests for form submission will work on
the client.

------
platz
[http://davmac.org/davpage/linux/async-
io.html](http://davmac.org/davpage/linux/async-io.html)

[https://blog.libtorrent.org/2012/10/asynchronous-disk-
io/](https://blog.libtorrent.org/2012/10/asynchronous-disk-io/)

