Skip to content

Commit fc5ef50

Browse files
authored
[Flight] Start initial work immediately (#30961)
In a past update we made render and prerender have different work scheduling behavior because these methods are meant to be used in differeent environments with different performance tradeoffs in mind. For instance to prioritize streaming we want to allow as much IO to complete before triggering a round of work because we want to flush as few intermediate UI states. With Prerendering there will never be any intermediate UI states so we can more aggressively render tasks as they complete. One thing we've found is that even during render we should ideally kick off work immediately. This update normalizes the intitial work for render and prerender to start in a microtask. Choosing microtask over sync is somewhat arbitrary but there really isn't a reason to make them different between render/prerender so for now we'll unify them and keep it as a microtask for now. This change also updates pinging behavior. If the request is still in the initial task that spawned it then pings will schedule on the microtask queue. This allows immediately available async APIs to resolve right away. The concern with doing this for normal pings is that it might crowd out IO events but since this is the initial task there would be IO to already be scheduled.
1 parent b75cc07 commit fc5ef50

File tree

1 file changed

+24
-25
lines changed

1 file changed

+24
-25
lines changed

packages/react-server/src/ReactFlightServer.js

Lines changed: 24 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -352,8 +352,17 @@ type Task = {
352352

353353
interface Reference {}
354354

355+
const OPENING = 10;
356+
const OPEN = 11;
357+
const ABORTING = 12;
358+
const CLOSING = 13;
359+
const CLOSED = 14;
360+
361+
const RENDER = 20;
362+
const PRERENDER = 21;
363+
355364
export type Request = {
356-
status: 10 | 11 | 12 | 13,
365+
status: 10 | 11 | 12 | 13 | 14,
357366
type: 20 | 21,
358367
flushScheduled: boolean,
359368
fatalError: mixed,
@@ -426,14 +435,6 @@ function defaultPostponeHandler(reason: string) {
426435
// Noop
427436
}
428437

429-
const OPEN = 10;
430-
const ABORTING = 11;
431-
const CLOSING = 12;
432-
const CLOSED = 13;
433-
434-
const RENDER = 20;
435-
const PRERENDER = 21;
436-
437438
function RequestInstance(
438439
this: $FlowFixMe,
439440
type: 20 | 21,
@@ -472,7 +473,7 @@ function RequestInstance(
472473
}
473474
const hints = createHints();
474475
this.type = type;
475-
this.status = OPEN;
476+
this.status = OPENING;
476477
this.flushScheduled = false;
477478
this.fatalError = null;
478479
this.destination = null;
@@ -1794,7 +1795,7 @@ function pingTask(request: Request, task: Task): void {
17941795
pingedTasks.push(task);
17951796
if (pingedTasks.length === 1) {
17961797
request.flushScheduled = request.destination !== null;
1797-
if (request.type === PRERENDER) {
1798+
if (request.type === PRERENDER || request.status === OPENING) {
17981799
scheduleMicrotask(() => performWork(request));
17991800
} else {
18001801
scheduleWork(() => performWork(request));
@@ -4062,21 +4063,18 @@ function flushCompletedChunks(
40624063

40634064
export function startWork(request: Request): void {
40644065
request.flushScheduled = request.destination !== null;
4065-
if (request.type === PRERENDER) {
4066-
if (supportsRequestStorage) {
4067-
scheduleMicrotask(() => {
4068-
requestStorage.run(request, performWork, request);
4069-
});
4070-
} else {
4071-
scheduleMicrotask(() => performWork(request));
4072-
}
4066+
if (supportsRequestStorage) {
4067+
scheduleMicrotask(() => {
4068+
requestStorage.run(request, performWork, request);
4069+
});
40734070
} else {
4074-
if (supportsRequestStorage) {
4075-
scheduleWork(() => requestStorage.run(request, performWork, request));
4076-
} else {
4077-
scheduleWork(() => performWork(request));
4078-
}
4071+
scheduleMicrotask(() => performWork(request));
40794072
}
4073+
scheduleWork(() => {
4074+
if (request.status === OPENING) {
4075+
request.status = OPEN;
4076+
}
4077+
});
40804078
}
40814079

40824080
function enqueueFlush(request: Request): void {
@@ -4129,7 +4127,8 @@ export function stopFlowing(request: Request): void {
41294127

41304128
export function abort(request: Request, reason: mixed): void {
41314129
try {
4132-
if (request.status === OPEN) {
4130+
// We define any status below OPEN as OPEN equivalent
4131+
if (request.status <= OPEN) {
41334132
request.status = ABORTING;
41344133
}
41354134
const abortableTasks = request.abortableTasks;

0 commit comments

Comments
 (0)