Skip to content

Commit 07def0c

Browse files
authored
Add test for throttling suspended siblings (#28361)
# Overview Adds a test to show the combination of the new throttling behavior and not pre-rendering siblings results in pushing out content that could have rendered much faster. - Without the new throttling, the sibling content would render in 30ms. - Without removing pre-rendering, the sibling content would render in 0ms. - With both, the sibling content takes 600ms. ## Example https://github.com/facebook/react/assets/2440089/abd62dc4-93f9-4b7b-a5aa-b795827c1a3a
1 parent 67e6fa6 commit 07def0c

File tree

1 file changed

+53
-0
lines changed

1 file changed

+53
-0
lines changed

packages/react-reconciler/src/__tests__/ReactSuspense-test.internal.js

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,59 @@ describe('ReactSuspense', () => {
289289
expect(container.textContent).toEqual('AB');
290290
});
291291

292+
it('pushes out siblings that render faster than throttle', async () => {
293+
function Foo() {
294+
Scheduler.log('Foo');
295+
return (
296+
<Suspense fallback={<Text text="Loading..." />}>
297+
<AsyncText text="A" ms={290} />
298+
<Suspense fallback={<Text text="Loading more..." />}>
299+
<AsyncText text="B" ms={30} />
300+
</Suspense>
301+
</Suspense>
302+
);
303+
}
304+
305+
setTimeout(async () => {
306+
// TODO: this is dumb, but AsyncText isn't timer based after the act changes.
307+
// Pretend that this is the start of the sibling suspending.
308+
// In a real test, the timer would start when we render B.
309+
setTimeout(async () => {
310+
resolveText('B');
311+
}, 30);
312+
313+
resolveText('A');
314+
}, 290);
315+
316+
// Render an empty shell
317+
const root = ReactTestRenderer.create(<Foo />, {
318+
isConcurrent: true,
319+
});
320+
321+
await waitForAll(['Foo', 'Suspend! [A]', 'Loading...']);
322+
expect(root).toMatchRenderedOutput('Loading...');
323+
324+
// Now resolve A
325+
jest.advanceTimersByTime(290);
326+
await waitFor(['A']);
327+
expect(root).toMatchRenderedOutput('Loading...');
328+
329+
// B starts loading. Parent boundary is in throttle.
330+
// Still shows parent loading under throttle
331+
jest.advanceTimersByTime(10);
332+
await waitForAll(['Suspend! [B]', 'Loading more...']);
333+
expect(root).toMatchRenderedOutput('Loading...');
334+
335+
// !! B could have finished before the throttle, but we show a fallback.
336+
// !! Pushing out the 30ms fetch for B to 300ms.
337+
jest.advanceTimersByTime(300);
338+
await waitFor(['B']);
339+
expect(root).toMatchRenderedOutput('ALoading more...');
340+
341+
await act(() => {});
342+
expect(root).toMatchRenderedOutput('AB');
343+
});
344+
292345
it('does not throttle fallback committing for too long', async () => {
293346
function Foo() {
294347
Scheduler.log('Foo');

0 commit comments

Comments
 (0)