
The Perils of Rehydration – A Realization about Gatsby and React - joshwcomeau
https://joshwcomeau.com/react/the-perils-of-rehydration
======
ehnto
Ignore React and all the community specific acronyms, you're talking about a
very fundamental problem that is technology agnostic and it's important to
understand it from that perspective, so you can take this knowledge with you
to any tool.

Whenever you try to precompile or even just cache an HTML file that relies on
run time data, you are going to have to build your application in a way that
is sympathetic to that. In most cases, you're going to have to figure out how
to fetch the missing data on the client side and populate it into the
template/runtime context.

This is an issue in Ruby, PHP, Javascript, React, Angular, Python... every
single application with caching or compilation.

~~~
mercer
This is one of the (many) reasons why I've started using Phoenix LiveView for
all the projects, when I can, that need either partial or full client-side
functionality.

By simply keeping all the state, logic, and rendering on the server, all sorts
of issues are avoided and various optimizations are possible, and I get full
server-side rendering for free!

The client-side, meanwhile, via websockets, only sends events to the server
and diffs whatever chunks of markup are sent back. Most of this is via server-
side provided attributes (phx-click, phx-change, etc.), but for the slightly
more 'exotic' stuff I can add my own events.

Obviously there are cases where this solution isn't practical, but this hasn't
been the case for the vast majority of my projects.

~~~
sojournerc
How does this scale? Having lots of concurrent websockets seems like it could
be challenging. Any caching layers?

~~~
namelosw
There are diff algorithms, but no caching layer.

Also Phoenix is written in Elixir which could easily handle millions of
stateful connections.

------
dgb23
I don’t quite understand why this pattern would be necessary. I would prefer
to render a ‚loading‘ state for dynamic components at build time, hydration
sees a valid state and the user gets a clear indication of what is going on.
Am I missing something?

~~~
joshwcomeau
Often, the data lives in localStorage, so it isn't really "loading". If your
data needs to be fetched asynchronously, a loading state is a fine solution.

Even in this case, a loading solution works just fine, but it's the exact same
pattern. You'd just `return <Spinner />` instead of `return null`. You also
face the same issue, if you don't wait until post-mount.

~~~
dgb23
I personally would rather defer reading from localStorage than defer rendering
a component. I don't want my components to know when and where they are
rendered.

------
pixelbreaker
This is a really useful post and explains the two-pass render paradigm really
well for me. Will be implementing in my work for sure.

------
nielsbot
I've hit this same issue myself when using Gatsby... Thanks for the clear and
informative post describing the cause AND providing a solution.

------
ThePhysicist
Interesting post, the fadeout effect on the top (in the mobile view) really
bothers me for some reason though.

------
_bxg1
At some point one just has to step back and question how necessary all of this
complexity is. This "best of both worlds" hybrid approach adds so many hidden
moving parts. I also don't really see why it's needed; the twin paradigms of
"lightweight web page" and "heavyweight web app" really seem like they neatly
cover the vast majority of cases.

