Skip to content

Commit e0da8db

Browse files
committed
[Flight] Avoid unnecessary indirection when serializing debug info
When a debug channel is hooked up, and we're serializing debug models, if the result is an already outlined reference, we can emit it directly, without also outlining the reference. This would create an unnecessary indirection. Before: ``` :N1760023808330.2688 0:D"$2" 0:D"$3" 0:D"$4" 0:"hi" 1:{"name":"Component","key":null,"env":"Server","stack":[],"props":{}} 2:{"time":3.0989999999999327} 3:"$1" 4:{"time":3.261792000000014} ``` After: ``` :N1760023786873.8916 0:D"$2" 0:D"$1" 0:D"$3" 0:"hi" 1:{"name":"Component","key":null,"env":"Server","stack":[],"props":{}} 2:{"time":2.4145829999999933} 3:{"time":2.5488749999999527} ``` Notice how the second debug info chunk is now directly referencing chunk `1` in the debug channel, without outlining and referencing `"$1"` as its own debug chunk `3`. This not only simplifies the RSC payload, and reduces overhead. But more importantly it helps the client resolve cyclic references when a model has debug info that has a reference back to the model. The client is currently not able to resolve such a cycle when those chunk indirections are involved. Ideally, we would also be able to resolve them regardless, but that requires more work. In the meantime, this fixes an immediate issue.
1 parent e29bb9d commit e0da8db

File tree

1 file changed

+15
-8
lines changed

1 file changed

+15
-8
lines changed

packages/react-server/src/ReactFlightServer.js

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4300,14 +4300,21 @@ function emitDebugChunk(
43004300

43014301
const json: string = serializeDebugModel(request, 500, debugInfo);
43024302
if (request.debugDestination !== null) {
4303-
// Outline the actual timing information to the debug channel.
4304-
const outlinedId = request.nextChunkId++;
4305-
const debugRow = outlinedId.toString(16) + ':' + json + '\n';
4306-
request.pendingDebugChunks++;
4307-
request.completedDebugChunks.push(stringToChunk(debugRow));
4308-
const row =
4309-
serializeRowHeader('D', id) + '"$' + outlinedId.toString(16) + '"\n';
4310-
request.completedRegularChunks.push(stringToChunk(row));
4303+
if (json[0] === '"' && json[1] === '$') {
4304+
// This is already an outlined reference so we can just emit it directly,
4305+
// without an unnecessary indirection.
4306+
const row = serializeRowHeader('D', id) + json + '\n';
4307+
request.completedRegularChunks.push(stringToChunk(row));
4308+
} else {
4309+
// Outline the debug information to the debug channel.
4310+
const outlinedId = request.nextChunkId++;
4311+
const debugRow = outlinedId.toString(16) + ':' + json + '\n';
4312+
request.pendingDebugChunks++;
4313+
request.completedDebugChunks.push(stringToChunk(debugRow));
4314+
const row =
4315+
serializeRowHeader('D', id) + '"$' + outlinedId.toString(16) + '"\n';
4316+
request.completedRegularChunks.push(stringToChunk(row));
4317+
}
43114318
} else {
43124319
const row = serializeRowHeader('D', id) + json + '\n';
43134320
request.completedRegularChunks.push(stringToChunk(row));

0 commit comments

Comments
 (0)