@samitouri / QOS-React / commits / 9406162bc9

[Flight] Emit start time before an await if one wasn't emitted already (#33646)

There's a special case where if we create a new task, e.g. to serialize a promise like `<div>{promise}</div>` then that row doesn't have any start time emitted but it has a `task.time` inherited. We mostly don't need this because every other operation emits its own start time. E.g. when we started rendering a Server Component or the real start time of a real `await`. For these implied awaits we don't have a start time. Ideally it would probably be when we started the serialization, like when we called `.then()` but we can't just emit that eagerly and we can't just advance the `task.time` because that time represents the last render or previous await and we use that to cut off awaits. However for this case we don't want to cut off any inner awaits inside the node we're serializing if they happened before the `.then()`. Therefore, I just use the time of the previous operation - which is likely either the resolution of a previous promise that blocked the `<div>` like the promise of the Server Component that rendered it, or just the start of the Server Component if it was sync.

Sebastian Markbåge committed Jun 25, 2025 at 17:28 UTC 9406162bc95f1db78169a7f5e11bc56d324b2071
1 file changed +8
packages/react-server/src/ReactFlightServer.js
+8
@@ -2211,6 +2211,10 @@ function emitAsyncSequence(
2211 debugInfo.stack = filterStackTrace(request, parseStackTrace(stack, 1));
2212 }
2213 }
2214 + // We don't have a start time for this await but in case there was no start time emitted
2215 + // we need to include something. TODO: We should maybe ideally track the time when we
2216 + // called .then() but without updating the task.time field since that's used for the cutoff.
2217 + advanceTaskTime(request, task, task.time);
2218 emitDebugChunk(request, task.id, debugInfo);
2219 // Mark the end time of the await. If we're aborting then we don't emit this
2220 // to signal that this never resolved inside this render.
@@ -4752,6 +4756,10 @@ function forwardDebugInfoFromAbortedTask(request: Request, task: Task): void {
4756 awaited: ((node: any): ReactIOInfo), // This is deduped by this reference.
4757 env: env,
4758 };
4759 + // We don't have a start time for this await but in case there was no start time emitted
4760 + // we need to include something. TODO: We should maybe ideally track the time when we
4761 + // called .then() but without updating the task.time field since that's used for the cutoff.
4762 + advanceTaskTime(request, task, task.time);
4763 emitDebugChunk(request, task.id, asyncInfo);
4764 } else {
4765 emitAsyncSequence(request, task, sequence, debugInfo, null, null);