diff --git a/compat/test/browser/suspense-hydration.test.js b/compat/test/browser/suspense-hydration.test.js
index 9143903238..b364cf41c6 100644
--- a/compat/test/browser/suspense-hydration.test.js
+++ b/compat/test/browser/suspense-hydration.test.js
@@ -97,6 +97,30 @@ describe('suspense hydration', () => {
});
});
+ it('should leave DOM untouched when suspending while hydrating', () => {
+ scratch.innerHTML = '
Hello
';
+ clearLog();
+
+ const [Lazy, resolve] = createLazy();
+ hydrate(
+
+
+ ,
+ scratch
+ );
+ rerender(); // Flush rerender queue to mimic what preact will really do
+ expect(scratch.innerHTML).to.equal('Hello
');
+ expect(getLog()).to.deep.equal([]);
+ clearLog();
+
+ return resolve(() => Hello
).then(() => {
+ rerender();
+ expect(scratch.innerHTML).to.equal('Hello
');
+ expect(getLog()).to.deep.equal([]);
+ clearLog();
+ });
+ });
+
it('should properly attach event listeners when suspending while hydrating', () => {
scratch.innerHTML = 'Hello
World
';
clearLog();
diff --git a/src/diff/index.js b/src/diff/index.js
index 3e4b17bd62..84c801bd02 100644
--- a/src/diff/index.js
+++ b/src/diff/index.js
@@ -273,13 +273,15 @@ export function diff(
newVNode._original = null;
// if hydrating or creating initial tree, bailout preserves DOM:
if (isHydrating || excessDomChildren != null) {
- newVNode._dom = oldDom;
newVNode._flags |= isHydrating
? MODE_HYDRATE | MODE_SUSPENDED
: MODE_HYDRATE;
+
+ while (oldDom && oldDom.nodeType === 8 && oldDom.nextSibling) {
+ oldDom = oldDom.nextSibling;
+ }
excessDomChildren[excessDomChildren.indexOf(oldDom)] = null;
- // ^ could possibly be simplified to:
- // excessDomChildren.length = 0;
+ newVNode._dom = oldDom;
} else {
newVNode._dom = oldVNode._dom;
newVNode._children = oldVNode._children;