@@ -400,6 +400,13 @@ type Preamble = PreambleState;
400
400
// 500 * 1024 / 8 * .8 * 0.5 / 2
401
401
const DEFAULT_PROGRESSIVE_CHUNK_SIZE = 12800 ;
402
402
403
+ function isEligibleForOutlining (
404
+ request : Request ,
405
+ boundary : SuspenseBoundary ,
406
+ ) : boolean {
407
+ return boundary . byteSize > request . progressiveChunkSize ;
408
+ }
409
+
403
410
function defaultErrorHandler ( error : mixed ) {
404
411
if (
405
412
typeof error === 'object' &&
@@ -1309,17 +1316,20 @@ function renderSuspenseBoundary(
1309
1316
queueCompletedSegment ( newBoundary , contentRootSegment ) ;
1310
1317
if ( newBoundary . pendingTasks === 0 && newBoundary . status === PENDING ) {
1311
1318
// This must have been the last segment we were waiting on. This boundary is now complete.
1312
- // Therefore we won't need the fallback. We early return so that we don't have to create
1313
- // the fallback.
1314
1319
newBoundary . status = COMPLETED ;
1315
- if ( request . pendingRootTasks === 0 && task . blockedPreamble ) {
1316
- // The root is complete and this boundary may contribute part of the preamble.
1317
- // We eagerly attempt to prepare the preamble here because we expect most requests
1318
- // to have few boundaries which contribute preambles and it allow us to do this
1319
- // preparation work during the work phase rather than the when flushing.
1320
- preparePreamble ( request ) ;
1320
+ // Therefore we won't need the fallback. We early return so that we don't have to create
1321
+ // the fallback. However, if this boundary ended up big enough to be eligible for outlining
1322
+ // we can't do that because we might still need the fallback if we outline it.
1323
+ if ( ! isEligibleForOutlining ( request , newBoundary ) ) {
1324
+ if ( request . pendingRootTasks === 0 && task . blockedPreamble ) {
1325
+ // The root is complete and this boundary may contribute part of the preamble.
1326
+ // We eagerly attempt to prepare the preamble here because we expect most requests
1327
+ // to have few boundaries which contribute preambles and it allow us to do this
1328
+ // preparation work during the work phase rather than the when flushing.
1329
+ preparePreamble ( request ) ;
1330
+ }
1331
+ return ;
1321
1332
}
1322
- return ;
1323
1333
}
1324
1334
} catch ( thrownValue : mixed ) {
1325
1335
newBoundary . status = CLIENT_RENDERED ;
@@ -4345,9 +4355,13 @@ function finishedTask(
4345
4355
// This needs to happen after we read the parentFlushed flags because aborting can finish
4346
4356
// work which can trigger user code, which can start flushing, which can change those flags.
4347
4357
// If the boundary was POSTPONED, we still need to finish the fallback first.
4358
+ // If the boundary is eligible to be outlined during flushing we can't cancel the fallback
4359
+ // since we might need it when it's being outlined.
4348
4360
if ( boundary . status === COMPLETED ) {
4349
- boundary . fallbackAbortableTasks . forEach ( abortTaskSoft , request ) ;
4350
- boundary . fallbackAbortableTasks . clear ( ) ;
4361
+ if ( ! isEligibleForOutlining ( request , boundary ) ) {
4362
+ boundary . fallbackAbortableTasks . forEach ( abortTaskSoft , request ) ;
4363
+ boundary . fallbackAbortableTasks . clear ( ) ;
4364
+ }
4351
4365
4352
4366
if (
4353
4367
request . pendingRootTasks === 0 &&
@@ -4957,7 +4971,7 @@ function flushSegment(
4957
4971
flushSubtree ( request , destination , segment , hoistableState ) ;
4958
4972
4959
4973
return writeEndPendingSuspenseBoundary ( destination , request . renderState ) ;
4960
- } else if ( boundary . byteSize > request . progressiveChunkSize ) {
4974
+ } else if ( isEligibleForOutlining ( request , boundary ) ) {
4961
4975
// This boundary is large and will be emitted separately so that we can progressively show
4962
4976
// other content. We add it to the queue during the flush because we have to ensure that
4963
4977
// the parent flushes first so that there's something to inject it into.
0 commit comments