Skip to content

Commit

Permalink
[Flight] Deduplicate suspended elements
Browse files Browse the repository at this point in the history
  • Loading branch information
unstubbable committed Apr 4, 2024
1 parent fd0da3e commit 06bb3fb
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 0 deletions.
70 changes: 70 additions & 0 deletions packages/react-client/src/__tests__/ReactFlight-test.js
Expand Up @@ -2145,4 +2145,74 @@ describe('ReactFlight', () => {
expect(loggedFn).not.toBe(foo);
expect(loggedFn.toString()).toBe(foo.toString());
});

// @gate __DEV__
it('does not emit duplicate chunks for already outlined elements in dev mode', async () => {
async function Bar({text}) {
return <div>{text.toUpperCase()}</div>;
}

function Foo() {
const bar = <Bar text="bar" />;

return (
<div>
{bar}
{bar}
</div>
);
}

const transport = ReactNoopFlightServer.render(<Foo />);
const textDecoder = new TextDecoder();

await act(async () => {
const chunks = transport
.map(chunk => textDecoder.decode(chunk).replace(/\n$/, ''))
.join('\n');

expect(chunks).toEqual(
`
0:D{"name":"Foo","env":"Server"}
1:D{"name":"Bar","env":"Server"}
0:["$","div",null,{"children":["$L1","$1"]}]
1:["$","div",null,{"children":"BAR"}]
`.trim(),
);
});
});

// @gate !__DEV__
it('does not emit duplicate chunks for already outlined elements in production mode', async () => {
async function Bar({text}) {
return <div>{text.toUpperCase()}</div>;
}

function Foo() {
const bar = <Bar text="bar" />;

return (
<div>
{bar}
{bar}
</div>
);
}

const transport = ReactNoopFlightServer.render(<Foo />);
const textDecoder = new TextDecoder();

await act(async () => {
const chunks = transport
.map(chunk => textDecoder.decode(chunk).replace(/\n$/, ''))
.join('\n');

expect(chunks).toEqual(
`
0:["$","div",null,{"children":["$L1","$1"]}]
1:["$","div",null,{"children":"BAR"}]
`.trim(),
);
});
});
});
3 changes: 3 additions & 0 deletions packages/react-server/src/ReactFlightServer.js
Expand Up @@ -1237,6 +1237,9 @@ function renderModel(
task.implicitSlot,
request.abortableTasks,
);
// The suspended element was outlined, so we're using the same ID for the
// original value, thus ensuring that it's deduplicated if it's referenced again.
request.writtenObjects.set((value: any), newTask.id);
const ping = newTask.ping;
(x: any).then(ping, ping);
newTask.thenableState = getThenableStateAfterSuspending();
Expand Down

0 comments on commit 06bb3fb

Please sign in to comment.