-
-
Notifications
You must be signed in to change notification settings - Fork 2k
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
Skip HTML comments during hydration #3771
Conversation
📊 Tachometer Benchmark ResultsSummaryduration
usedJSHeapSize
Results02_replace1k
duration
usedJSHeapSize
run-warmup-0
run-warmup-1
run-warmup-2
run-warmup-3
run-warmup-4
run-final
03_update10th1k_x16
duration
usedJSHeapSize
07_create10k
duration
usedJSHeapSize
filter_list
duration
usedJSHeapSize
hydrate1k
duration
usedJSHeapSize
many_updates
duration
usedJSHeapSize
text_update
duration
usedJSHeapSize
todo
duration
usedJSHeapSize
|
Size Change: +137 B (0%) Total Size: 54.5 kB
ℹ️ View Unchanged
|
@@ -92,6 +92,7 @@ describe('hydrate()', () => { | |||
scratch | |||
); | |||
expect(scratch.innerHTML).to.equal('<p><i>0</i><b>1</b></p>'); | |||
expect(getLog()).to.deep.equal(['Comment.remove()']); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's strange that we end up removing the comment. I would have thought it would be skipped and ignored?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IIUC, the comment will get removed in diffElementNodes here: https://github.com/preactjs/preact/blob/master/src/diff/index.js#L447-L451
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assume for streaming we need to preserve these nodes until they are revived?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah. Ideally we would just walk over them and ignore, but I guess we need to do that in two places due to this being a new type of Node to deal with (vs skipped Text/Element nodes, which we always walk here)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
An alternative would be to special case a branch for selective hydration where we manually walk over the comment nodes as part of diff:
if (vnode.type === Island) {
// We know that island is surrounded with comment nodes
oldDom = oldDom.nextSibling
}
Was thinking some more about comment nodes and I'm not sure how they would behave if we'd just skip over them. Imagine a scenario where we'll support selective hydration and have a non-hydrated subtree marked with comment nodes that is only activated when the user hovers with the mouse over the area or otherwise interacts with it. In that scenario we'd likely be rendering on the client already before all subtrees are hydrated.
This could have an effect on our ordering:
<div>
<A />
<B />
<NonHydrated />
<C />
</div>
Now, if we render on the client and need to re-order nodes due to various conditional rendering, our skip comment logic would likely bias in favor of moving the comments at the end of the childNode list.
I'm wondering if that means that we'd need to move the comment node as part of NonHydrated
here. That would ensure that the order is always correct.
// in diff so that the vnode tree matches the DOM tree again. | ||
do { | ||
oldDom = oldDom.nextSibling; | ||
} while (oldDom !== null && oldDom.nodeType === 8); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if it would be possible to use a similar (or the same somehow?) check to the one we have for node types here?
Lines 358 to 359 in de08e91
'setAttribute' in child === !!nodeType && | |
(nodeType ? child.localName === nodeType : child.nodeType === 3) |
The other one knows what type it's looking for, so maybe it isn't possible? Just trying to think of ways to avoid checking the nodeType
getter.
b844b56
to
d128bf4
Compare
d128bf4
to
d35efab
Compare
Superseded by #4128 |
We'd unnecessarily move nodes when the HTML we're going to hydrate contains comments. This is expected because it's sort of a mismatch between the SSR'd tree vs the virtual tree. But it turns out that this feature is needed for streaming SSR as comment nodes are used to indicate hydration boundaries.
Fixes #3767 .