@samitouri / QOS-React-2 / commits / 321087d134

[Fizz] Don't add aborted segments to the completedSegments list (#21976)

* Don't add aborted segments to the completedSegments list * Update error message to include aborted status

Sebastian Markbåge committed Jul 27, 2021 at 21:53 UTC 321087d1343638e2d45e53971a7d8c384549940b
3 files changed +50 -11
packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js
+31
@@ -1447,4 +1447,35 @@ describe('ReactDOMFizzServer', () => {
1447
1448 expect(loggedErrors).toEqual([theError]);
1449 });
1450 +
1451 + // @gate experimental
1452 + it('should be able to abort the fallback if the main content finishes first', async () => {
1453 + await act(async () => {
1454 + const {startWriting} = ReactDOMFizzServer.pipeToNodeWritable(
1455 + <Suspense fallback={<Text text="Loading Outer" />}>
1456 + <div>
1457 + <Suspense
1458 + fallback={
1459 + <div>
1460 + <AsyncText text="Loading" />
1461 + Inner
1462 + </div>
1463 + }>
1464 + <AsyncText text="Hello" />
1465 + </Suspense>
1466 + </div>
1467 + </Suspense>,
1468 + writable,
1469 + );
1470 + startWriting();
1471 + });
1472 + expect(getVisibleChildren(container)).toEqual('Loading Outer');
1473 + // We should have received a partial segment containing the a partial of the fallback.
1474 + expect(container.innerHTML).toContain('Inner');
1475 + await act(async () => {
1476 + resolveText('Hello');
1477 + });
1478 + // We should've been able to display the content without waiting for the rest of the fallback.
1479 + expect(getVisibleChildren(container)).toEqual(<div>Hello</div>);
1480 + });
1481 });
packages/react-server/src/ReactFizzServer.js
+18 -10
@@ -1408,7 +1408,11 @@ function finishedTask(
1408 // This must have been the last segment we were waiting on. This boundary is now complete.
1409 if (segment.parentFlushed) {
1410 // Our parent segment already flushed, so we need to schedule this segment to be emitted.
1411 - boundary.completedSegments.push(segment);
1411 + // If it is a segment that was aborted, we'll write other content instead so we don't need
1412 + // to emit it.
1413 + if (segment.status === COMPLETED) {
1414 + boundary.completedSegments.push(segment);
1415 + }
1416 }
1417 if (boundary.parentFlushed) {
1418 // The segment might be part of a segment that didn't flush yet, but if the boundary's
@@ -1423,14 +1427,18 @@ function finishedTask(
1427 } else {
1428 if (segment.parentFlushed) {
1429 // Our parent already flushed, so we need to schedule this segment to be emitted.
1426 - const completedSegments = boundary.completedSegments;
1427 - completedSegments.push(segment);
1428 - if (completedSegments.length === 1) {
1429 - // This is the first time since we last flushed that we completed anything.
1430 - // We can schedule this boundary to emit its partially completed segments early
1431 - // in case the parent has already been flushed.
1432 - if (boundary.parentFlushed) {
1433 - request.partialBoundaries.push(boundary);
1430 + // If it is a segment that was aborted, we'll write other content instead so we don't need
1431 + // to emit it.
1432 + if (segment.status === COMPLETED) {
1433 + const completedSegments = boundary.completedSegments;
1434 + completedSegments.push(segment);
1435 + if (completedSegments.length === 1) {
1436 + // This is the first time since we last flushed that we completed anything.
1437 + // We can schedule this boundary to emit its partially completed segments early
1438 + // in case the parent has already been flushed.
1439 + if (boundary.parentFlushed) {
1440 + request.partialBoundaries.push(boundary);
1441 + }
1442 }
1443 }
1444 }
@@ -1570,7 +1578,7 @@ function flushSubtree(
1578 default: {
1579 invariant(
1580 false,
1573 - 'Errored or already flushed boundaries should not be flushed again. This is a bug in React.',
1581 + 'Aborted, errored or already flushed boundaries should not be flushed again. This is a bug in React.',
1582 );
1583 }
1584 }
scripts/error-codes/codes.json
+1 -1
@@ -378,7 +378,7 @@
378 "387": "Should have a current fiber. This is a bug in React.",
379 "388": "Expected to find a bailed out fiber. This is a bug in React.",
380 "389": "There can only be one root segment. This is a bug in React.",
381 - "390": "Errored or already flushed boundaries should not be flushed again. This is a bug in React.",
381 + "390": "Aborted, errored or already flushed boundaries should not be flushed again. This is a bug in React.",
382 "391": "A previously unvisited boundary must have exactly one root segment. This is a bug in React.",
383 "392": "A root segment ID must have been assigned by now. This is a bug in React.",
384 "393": "Cache cannot be refreshed during server rendering.",