@samitouri / QOS-React / commits / ab24f643d0

[Fizz] use microtasks rather than tasks when scheduling work while prerendering (#30770)

Similar to https://github.com/facebook/react/pull/30768 we want to schedule work during prerendering in microtasks both for the root task and pings. We continue to schedule flushes as Tasks to allow as much work to be batched up as possible.

Josh Story committed Aug 21, 2024 at 07:55 UTC ab24f643d0809ee09a7499862fef135fb09a0225
1 file changed +21 -6
packages/react-server/src/ReactFizzServer.js
+21 -6
@@ -38,6 +38,7 @@ import {describeObjectForErrorMessage} from 'shared/ReactSerializationErrors';
38
39 import {
40 scheduleWork,
41 + scheduleMicrotask,
42 beginWriting,
43 writeChunk,
44 writeChunkAndReturn,
@@ -669,7 +670,11 @@ function pingTask(request: Request, task: Task): void {
670 pingedTasks.push(task);
671 if (request.pingedTasks.length === 1) {
672 request.flushScheduled = request.destination !== null;
672 - scheduleWork(() => performWork(request));
673 + if (request.trackedPostpones !== null) {
674 + scheduleMicrotask(() => performWork(request));
675 + } else {
676 + scheduleWork(() => performWork(request));
677 + }
678 }
679 }
680
@@ -4893,12 +4898,22 @@ function flushCompletedQueues(
4898
4899 export function startWork(request: Request): void {
4900 request.flushScheduled = request.destination !== null;
4896 - if (supportsRequestStorage) {
4897 - scheduleWork(() => requestStorage.run(request, performWork, request));
4901 + if (request.trackedPostpones !== null) {
4902 + // When prerendering we use microtasks for pinging work
4903 + if (supportsRequestStorage) {
4904 + scheduleMicrotask(() =>
4905 + requestStorage.run(request, performWork, request),
4906 + );
4907 + } else {
4908 + scheduleMicrotask(() => performWork(request));
4909 + }
4910 } else {
4899 - scheduleWork(() => performWork(request));
4900 - }
4901 - if (request.trackedPostpones === null) {
4911 + // When rendering/resuming we use regular tasks and we also emit early preloads
4912 + if (supportsRequestStorage) {
4913 + scheduleWork(() => requestStorage.run(request, performWork, request));
4914 + } else {
4915 + scheduleWork(() => performWork(request));
4916 + }
4917 // this is either a regular render or a resume. For regular render we want
4918 // to call emitEarlyPreloads after the first performWork because we want
4919 // are responding to a live request and need to balance sending something early