I've been reviewing the Directives Hydration approach with @mtias, and he suggested limiting the hydration to the smallest area possible when the site won't do client-side navigations.
Even though our initial tests suggest that the toVdom function is faster than we initially thought, I agree that we should try it because it will improve performance and increase backward compatibility.
I've been thinking about it, and I believe it shouldn't add much complexity to the system. I've recorded a video to explain how I would approach it, which is basically:
- Use blocks as the "hydratable" unit (not directives or client components).
- Use
block.json for the hydration opt-in.
- Blocks need to declare the type of hydration they require, depending on if the block interacts with their inner blocks or not (through context, error boundaries, suspense, etc.):
- Isolated:
- If the block doesn't interact with its inner blocks
- The
toVdom algorithm stops when it finds the wp-inner-block attributes.
- Top-down:
- If the block interacts with its inner blocks (context, error boundaries, suspense, etc.)
- The
toVdom algorithm doesn't stop: everything in the tree below that block belongs to the same "app", including all their inner blocks. No interblock-sync is required (as opposed to the custom elements approach).
https://www.loom.com/share/3b4cb16c5b6c41d69f707b196cffb7f7
https://excalidraw.com/#json=sk6HaigLP3YGxVq8tTo-H,HeYfhO2lmY4zC1uwdF5H6g
I've also been exploring if there would be a way to "upgrade" a page that was hydrated using this partial vDOM hydration to directives hydration by reusing the vnodes created by the initial islands in the full app, but it requires manual mutation of the vnodes, and it feels to hacky for the moment. I also wasn't able to reuse the useEffect hooks (they are triggered again). I mentioned it in Preact's Slack, and Marvin said they are exploring islands in Preact, so maybe we can collaborate with them in the future. For now, I would discard that path.