A certain tree of <Suspense> components, some of which are inside <Fragment>, getting resolved in a particular order can cause the DOM order to become scrambled.
Here is a test reproducing the issue (using the helpers from the suspense.test.js file):
it('should correctly render Suspense components inside Fragments', async () => {
const [Lazy1, resolve1] = createLazy();
const [Lazy2, resolve2] = createLazy();
const [Lazy3, resolve3] = createLazy();
const Loading = () => <div>Suspended...</div>;
const loadingHtml = `<div>Suspended...</div>`;
render(
<Fragment>
<Suspense fallback={<Loading />}>
<Lazy1 />
</Suspense>
<Fragment>
<Suspense fallback={<Loading />}>
<Lazy2 />
</Suspense>
</Fragment>
<Suspense fallback={<Loading />}>
<Lazy3 />
</Suspense>
</Fragment>,
scratch
);
rerender();
expect(scratch.innerHTML).to.eql(
`${loadingHtml}${loadingHtml}${loadingHtml}`
);
await resolve2(() => <span>2</span>);
await resolve1(() => <span>1</span>);
rerender();
expect(scratch.innerHTML).to.eql(
`<span>1</span><span>2</span>${loadingHtml}`
);
await resolve3(() => <span>3</span>);
rerender();
expect(scratch.innerHTML).to.eql(
`<span>1</span><span>2</span><span>3</span>`
);
});
The second assertion fails, because the HTML output is <span>2</span><div>Suspended...</div><span>1</span>, i.e. the first component's DOM gets bumped to the end of the DOM.
Tested on Preact 10.0.5.
A certain tree of
<Suspense>components, some of which are inside<Fragment>, getting resolved in a particular order can cause the DOM order to become scrambled.Here is a test reproducing the issue (using the helpers from the
suspense.test.jsfile):The second assertion fails, because the HTML output is
<span>2</span><div>Suspended...</div><span>1</span>, i.e. the first component's DOM gets bumped to the end of the DOM.Tested on Preact 10.0.5.