mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
[Flight] Schedule work in a microtask (#29491)
Stacked on #29551 Flight pings much more often than Fizz because async function components will always take at least a microtask to resolve . Rather than scheduling this work as a new macrotask Flight now schedules pings in a microtask. This allows more microtasks to ping before actually doing a work flush but doesn't force the vm to spin up a new task which is quite common give n the nature of Server Components
This commit is contained in:
@@ -20,6 +20,14 @@ export function scheduleWork(callback: () => void) {
|
||||
callback();
|
||||
}
|
||||
|
||||
export function scheduleMicrotask(callback: () => void) {
|
||||
// While this defies the method name the legacy builds have special
|
||||
// overrides that make work scheduling sync. At the moment scheduleMicrotask
|
||||
// isn't used by any legacy APIs so this is somewhat academic but if they
|
||||
// did in the future we'd probably want to have this be in sync with scheduleWork
|
||||
callback();
|
||||
}
|
||||
|
||||
export function flushBuffered(destination: Destination) {}
|
||||
|
||||
export function beginWriting(destination: Destination) {}
|
||||
|
||||
@@ -25,6 +25,9 @@ type Destination = Array<Uint8Array>;
|
||||
const textEncoder = new TextEncoder();
|
||||
|
||||
const ReactNoopFlightServer = ReactFlightServer({
|
||||
scheduleMicrotask(callback: () => void) {
|
||||
callback();
|
||||
},
|
||||
scheduleWork(callback: () => void) {
|
||||
callback();
|
||||
},
|
||||
|
||||
@@ -74,6 +74,9 @@ function write(destination: Destination, buffer: Uint8Array): void {
|
||||
}
|
||||
|
||||
const ReactNoopServer = ReactFizzServer({
|
||||
scheduleMicrotask(callback: () => void) {
|
||||
callback();
|
||||
},
|
||||
scheduleWork(callback: () => void) {
|
||||
callback();
|
||||
},
|
||||
|
||||
+2
-1
@@ -26,6 +26,7 @@ import {enableFlightReadableStream} from 'shared/ReactFeatureFlags';
|
||||
|
||||
import {
|
||||
scheduleWork,
|
||||
scheduleMicrotask,
|
||||
flushBuffered,
|
||||
beginWriting,
|
||||
writeChunkAndReturn,
|
||||
@@ -1571,7 +1572,7 @@ function pingTask(request: Request, task: Task): void {
|
||||
pingedTasks.push(task);
|
||||
if (pingedTasks.length === 1) {
|
||||
request.flushScheduled = request.destination !== null;
|
||||
scheduleWork(() => performWork(request));
|
||||
scheduleMicrotask(() => performWork(request));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,21 @@ export function scheduleWork(callback: () => void) {
|
||||
channel.port2.postMessage(null);
|
||||
}
|
||||
|
||||
function handleErrorInNextTick(error: any) {
|
||||
setTimeout(() => {
|
||||
throw error;
|
||||
});
|
||||
}
|
||||
|
||||
const LocalPromise = Promise;
|
||||
|
||||
export const scheduleMicrotask: (callback: () => void) => void =
|
||||
typeof queueMicrotask === 'function'
|
||||
? queueMicrotask
|
||||
: callback => {
|
||||
LocalPromise.resolve(null).then(callback).catch(handleErrorInNextTick);
|
||||
};
|
||||
|
||||
export function flushBuffered(destination: Destination) {
|
||||
// WHATWG Streams do not yet have a way to flush the underlying
|
||||
// transform streams. https://github.com/whatwg/streams/issues/960
|
||||
|
||||
@@ -25,6 +25,8 @@ export function scheduleWork(callback: () => void) {
|
||||
setTimeout(callback, 0);
|
||||
}
|
||||
|
||||
export const scheduleMicrotask = queueMicrotask;
|
||||
|
||||
export function flushBuffered(destination: Destination) {
|
||||
// Bun direct streams provide a flush function.
|
||||
// If we don't have any more data to send right now.
|
||||
|
||||
@@ -13,6 +13,21 @@ export type PrecomputedChunk = Uint8Array;
|
||||
export opaque type Chunk = Uint8Array;
|
||||
export type BinaryChunk = Uint8Array;
|
||||
|
||||
function handleErrorInNextTick(error: any) {
|
||||
setTimeout(() => {
|
||||
throw error;
|
||||
});
|
||||
}
|
||||
|
||||
const LocalPromise = Promise;
|
||||
|
||||
export const scheduleMicrotask: (callback: () => void) => void =
|
||||
typeof queueMicrotask === 'function'
|
||||
? queueMicrotask
|
||||
: callback => {
|
||||
LocalPromise.resolve(null).then(callback).catch(handleErrorInNextTick);
|
||||
};
|
||||
|
||||
export function scheduleWork(callback: () => void) {
|
||||
setTimeout(callback, 0);
|
||||
}
|
||||
|
||||
@@ -26,6 +26,8 @@ export function scheduleWork(callback: () => void) {
|
||||
setImmediate(callback);
|
||||
}
|
||||
|
||||
export const scheduleMicrotask = queueMicrotask;
|
||||
|
||||
export function flushBuffered(destination: Destination) {
|
||||
// If we don't have any more data to send right now.
|
||||
// Flush whatever is in the buffer to the wire.
|
||||
|
||||
@@ -31,6 +31,7 @@ export opaque type Chunk = mixed; // eslint-disable-line no-undef
|
||||
export opaque type BinaryChunk = mixed; // eslint-disable-line no-undef
|
||||
|
||||
export const scheduleWork = $$$config.scheduleWork;
|
||||
export const scheduleMicrotask = $$$config.scheduleMicrotask;
|
||||
export const beginWriting = $$$config.beginWriting;
|
||||
export const writeChunk = $$$config.writeChunk;
|
||||
export const writeChunkAndReturn = $$$config.writeChunkAndReturn;
|
||||
|
||||
@@ -60,6 +60,8 @@ export function scheduleWork(callback: () => void) {
|
||||
LocalPromise.resolve().then(callback).catch(handleErrorInNextTick);
|
||||
}
|
||||
|
||||
export const scheduleMicrotask: (callback: () => void) => void = scheduleWork;
|
||||
|
||||
export function beginWriting(destination: Destination) {
|
||||
destination.beginWriting();
|
||||
}
|
||||
|
||||
@@ -9,6 +9,10 @@
|
||||
|
||||
export * from '../ReactServerStreamConfigFB';
|
||||
|
||||
export function scheduleMicrotask(callback: () => void) {
|
||||
// We don't schedule work in this model, and instead expect performWork to always be called repeatedly.
|
||||
}
|
||||
|
||||
export function scheduleWork(callback: () => void) {
|
||||
// We don't schedule work in this model, and instead expect performWork to always be called repeatedly.
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user