Skip to content

Instantly share code, notes, and snippets.

@LukasBombach
Last active July 20, 2023 15:00
Show Gist options
  • Save LukasBombach/6932689d5063d501072bb2f8319f8070 to your computer and use it in GitHub Desktop.
Save LukasBombach/6932689d5063d501072bb2f8319f8070 to your computer and use it in GitHub Desktop.

Partial Hydration

If you do server side rendering (SSR) you don't necessarily need to hydrate your entire page if most of your content ist static and only some parts are interactive / dynamic. That is especially true for a newspaper website, which ich what we are working on.

What you want is partial hydration, sometimes called or related to progressive hydration or lazy hydration.

There are a few implementations out there to achive this, for instance second-dehydrator (made by developers at the BBC) or React Prerendered Component (which has incomprehensive documentation).

How to do it

The basic idea is to add markers to you SSR rendered DOM that tell you which DOM element maps to which component and what their props have been. Example:

<ComponentA />
<Hydrate>
  <ComponentB prop="1" />
  <ComponentB prop="2" />
</Hydrate>

could create markup like

<span>Component A</span>
<script type="appication/hydration-marker" hydration-id="xyz"></script>
<span>Component B 1</span>
<span>Component B 2</span>
<!-- lots of dom -->
<script type="appication/hydration-data">{ "xyz": [{name="ComponentB", prop: "1"}, {name="ComponentB", prop: "2"}] }</script>
</body>

Now a script could find the marker and the data and intrinsically know that the next 2 html elements (the length of the data corresponding to the id "xyz") should be hydrated with ComponentB and the corresponding props.

Here is an implementation of that (active wip) https://github.com/spring-media/bscmp-evaluation-next-suspense/

The Problem

If we do this:

import { render } from 'preact';
import ComponentB from "./componentb";

const el = findComponentBDomElememnt(); // <span>Component B 1</span>
render(ComponentB, el);

It will actually create this kind of markup (of course):

<span>
  <span>Component B 1</span>
</span>

because it uses the outmost element of ComponentB as wrapper for ComponentB to append the component into.

Question

Is there any way we can hydrate the exact element matching the component in the DOM and replace that element, rather than appending into that element? Would it be possible by accessing lower level functions of preact? Would it even be in the scope if something for the future?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment