-
Notifications
You must be signed in to change notification settings - Fork 49.3k
[Fizz] Support SuspenseList revealOrder="together" #33311
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
f5373e4
to
0eaab16
Compare
@@ -194,6 +193,10 @@ export function getViewTransitionFormatContext( | |||
return parentContext; | |||
} | |||
|
|||
export function canHavePreamble(): boolean { | |||
return false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@gnoff Top level Suspense creates a scenario where you sometimes have to emit some kind of top level HTML tag to force Suspense boundaries to flush early. This shouldn't be necessary in renderToString
which is a legacy API.
I think I can basically disable the feature this way.
dfe8b08
to
f977259
Compare
if (allComplete) { | ||
unblockSuspenseListRow(request, row); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This optimization wouldn't be safe if this had some hoistable state because it would not have been hoisted as part of hoistPreambleState
since these boundaries weren't COMPLETE
by the time we started flushing the shell.
Not sure how to solve that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably have to find a way to move this optimization earlier.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moved to render phase. 1c50823
f977259
to
1c50823
Compare
…future rows (#33312) Stacked on #33311. When a row contains Suspense boundaries that themselves depend on CSS, they will not resolve until the CSS has loaded on the client. We need future rows in a list to be blocked until this happens. We could do something in the runtime but a simpler approach is to just add those CSS dependencies to all those boundaries as well. To do this, we first hoist the HoistableState from a completed boundary onto its parent row. Then when the row finishes do we hoist it onto the next row and onto any boundaries within that row.
Stacked on #33308. For "together" mode, we can be a self-blocking row that adds all its boundaries to the blocked set, but there's no parent row that unblocks it. A particular quirk of this mode is that it's not enough to just unblock them all on the server together. Because if one boundary downloads all its html and then issues a complete instruction it'll appear before the others while streaming in. What we actually want is to reveal them all in a single batch. This implementation takes a short cut by unblocking the rows in `flushPartialBoundary`. That ensures that all the segments of every boundary has a chance to flush before we start emitting any of the complete boundary instructions. Once the last one unblocks, all the complete boundary instructions are queued. Ideally this would be a single `<script>` tag so that they can't be split up even if we get a chunk containing some of them. ~A downside of this approach is that we always outline these boundaries. We could inline them if they all complete before the parent flushes. E.g. by checking if the row is blocked only by its own boundaries and if all the boundaries would fit without getting outlined, then we can inline them all at once.~ I went ahead and did this because it solves an issue with `renderToString` where it doesn't support the script runtime so it can only handle this if inlined. DiffTrain build for [99aa685](99aa685)
…future rows (#33312) Stacked on #33311. When a row contains Suspense boundaries that themselves depend on CSS, they will not resolve until the CSS has loaded on the client. We need future rows in a list to be blocked until this happens. We could do something in the runtime but a simpler approach is to just add those CSS dependencies to all those boundaries as well. To do this, we first hoist the HoistableState from a completed boundary onto its parent row. Then when the row finishes do we hoist it onto the next row and onto any boundaries within that row. DiffTrain build for [50389e1](50389e1)
Stacked on #33308.
For "together" mode, we can be a self-blocking row that adds all its boundaries to the blocked set, but there's no parent row that unblocks it.
A particular quirk of this mode is that it's not enough to just unblock them all on the server together. Because if one boundary downloads all its html and then issues a complete instruction it'll appear before the others while streaming in. What we actually want is to reveal them all in a single batch.
This implementation takes a short cut by unblocking the rows in
flushPartialBoundary
. That ensures that all the segments of every boundary has a chance to flush before we start emitting any of the complete boundary instructions. Once the last one unblocks, all the complete boundary instructions are queued. Ideally this would be a single<script>
tag so that they can't be split up even if we get a chunk containing some of them.A downside of this approach is that we always outline these boundaries. We could inline them if they all complete before the parent flushes. E.g. by checking if the row is blocked only by its own boundaries and if all the boundaries would fit without getting outlined, then we can inline them all at once.I went ahead and did this because it solves an issue withrenderToString
where it doesn't support the script runtime so it can only handle this if inlined.