Skip to content
This repository has been archived by the owner on Jul 28, 2023. It is now read-only.

Limit the hydration of the Directives Hydration when the site doesn't support client-side navigations #93

Closed
luisherranz opened this issue Oct 26, 2022 · 4 comments · Fixed by #124

Comments

@luisherranz
Copy link
Member

luisherranz commented Oct 26, 2022

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.

@michalczaplinski
Copy link
Collaborator

michalczaplinski commented Dec 6, 2022

@luisherranz has been exploring an initial solution to this problem in this stackblitz.

It definitely looks like a step in the right direction! But the problem is that after "upgrading" the island its hooks run twice.

I have been studying this approach a bit but havent come up with a solution yet. Some of the things I've tried are:

  • Cloning the island before attaching it to the vDOM. It looks something like this:

      document.body.__k.__k[0].__k[7].__k[1].__k = clone(window.island1.__k.__k);

    This has a different problem:

    • The hooks stay attached to the original (non-cloned) reference.
    • The new (cloned) island does not have any hooks - presumably they cannot be cloned:
    Screenshot 2022-12-05 at 22 30 13
  • Find the offending bit of code that causes the hooks to run twice.
    The main difficulty with this is the mangling of the properties. I've figured out how to set up vite so that it does not mangle them. Here's the stackblitz with the setup

Will continue to investigate this. Next steps would be to step with a debugger through the unmangled preact/hooks to see why the hooks run twice.

@luisherranz
Copy link
Member Author

luisherranz commented Dec 12, 2022

I gave up because it felt too hacky to me. At this point, I think Preact needs to provide more tools to support different flavors of partial hydration without having to hack into their internals.

That doesn't prevent us from limiting the hydration to smaller islands when client-side navigations are not possible, though.

@michalczaplinski
Copy link
Collaborator

Makes sense. For what it's worth, I've already spent some time on this:

Will continue to investigate this. Next steps would be to step with a debugger through the unmangled preact/hooks to see why the hooks run twice.

Came up empty handed so far. I think we can present our use case to the Preact team so that they can consider adding first-class support for this.

@luisherranz
Copy link
Member Author

luisherranz commented Dec 20, 2022

@SantosGuillamot SantosGuillamot changed the title Limit the hydration of the full vDOM when the site doesn't support client-side transitions Limit the hydration of the Directives Hydration when the site doesn't support client-side transitions Jan 11, 2023
@luisherranz luisherranz changed the title Limit the hydration of the Directives Hydration when the site doesn't support client-side transitions Limit the hydration of the Directives Hydration when the site doesn't support client-side navigations Jan 30, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
2 participants