Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hydration removes and add nodes again when there are HTML comments just before them #3767

Closed
1 task done
luisherranz opened this issue Oct 14, 2022 · 5 comments · May be fixed by #3771
Closed
1 task done

Hydration removes and add nodes again when there are HTML comments just before them #3767

luisherranz opened this issue Oct 14, 2022 · 5 comments · May be fixed by #3771

Comments

@luisherranz
Copy link

  • Check if updating to the latest Preact version resolves the issue

Describe the bug

Preact unnecessarily removes and adds the DOM nodes that it finds after HTML comments during hydration.

<div id="root">
    <div>I'm going to be preserved in the DOM</div>
    <!-- I'm a comment, so I'll be removed, which is also fine -->
    <div>I'll be removed and added back again</div>
</div>

To Reproduce

I reproduced the bug in this repository: https://github.com/luisherranz/preact-comments-hydration-bug (Open with Stackblitz Codeflow)

And this is a branch with a Mutation Observer added to the current hydration tests.

Steps to reproduce the behavior:

  1. Add a comment to the SSR'ed HTML
  2. Monitor changes to the DOM
  3. Hydrate it with Preact
  4. The nodes after the HTML comment are removed and added again

There is a video with a longer explanation on this other issue.

Expected behavior

Preact should remove the comments, but it should preserve the rest of the DOM nodes.

@marvinhagemeister
Copy link
Member

It's more of a mismatch between the virtual tree and what's in the DOM tree because the comments were injected outside of preact-render-to-string somehow. Not sure if that makes this a bug or more of a feature request to allow skipping comment nodes that weren't created by Preact. Conceptually, the SSR'ed tree must match the virtual tree 1:1 and not be messed with.

Made a PR that would address this over here: #3771

That said I'm not sure if we should merge it as the use case seems to be a bit niche. I'd love to know more about where the comments are coming from in your scenario. It seems to be related to how WordPress' editor's HTML is generated. Can you share more information on that?

@luisherranz
Copy link
Author

Thanks for the explanation, and thanks for looking into this, Marvin. If this is actually the expected behavior in Preact, then we may need to look for an alternative solution.

For context, this is not specifically related to WordPress, but to the partial hydration technique we are trying to implement, which:

  • It traverses the DOM to generate a static virtual DOM.
  • While doing so, it replaces the interactive parts of that virtual DOM with client components.

The main benefit of that technique (versus the Astro-like island approach) is that interisland communication works out of the box (context, suspense, error boundaries) and it can do client-side transitions. In a way, it's similar to RSC, but lightweight and built on top of regular HTML. The initial HTML can be generated by any technology, not preact-render-to-string. In our case, the HTML is generated by WordPress, but it could be any other platform/language. And that HTML can contain anything, including HTML comments.

Actually, WordPress discourages using HTML comments as they are usually removed by optimization plugins or CDNs (Cloudflare and the like), but WordPress developers still add them sometimes.

The ideal solution would be to add the HTML comments to the static virtual DOM and have a 1:1 match. But Preact is not prepared to deal with comment vnodes (the diffing fails).

Now that I know that this is the expected behavior and not a bug, we'll try to deal with it ourselves. Maybe removing the comments during the DOM -> vDOM phase.

@marvinhagemeister
Copy link
Member

@luisherranz Don't get me wrong, I'm happy to add support for this if there is a strong reason to do so. And it might look like I need that feature for streaming hydration anyway as the pending areas need to be marked with HTML comments.

@luisherranz
Copy link
Author

the pending areas need to be marked with HTML comments

Oh, interesting (and exciting) 🙂

What's your idea about that part? (for example, is the idea to keep vnode representations of those HTML comments in the vdom while the rest of the HTML is streamed?)

@luisherranz
Copy link
Author

I'm going to close this issue as this works as expected, and we will manually remove the HTML comments during our DOM -> vDOM step. I'll keep an eye on what you release for streaming in case we can adopt it in the future!

@luisherranz luisherranz closed this as not planned Won't fix, can't repro, duplicate, stale Oct 17, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants