-
Notifications
You must be signed in to change notification settings - Fork 48.8k
[Fizz] Support basic SuspenseList forwards/backwards revealOrder #33306
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
Backwards row are rendered in reverse order but flushed in the right order using the segments.
… them Not covered by Suspense boundaries. While these already block the parent, it is needed to know whether we might discover more Suspense boundaries later.
However, if a boundary might get outlined, then we can't consider it complete until it actually gets written. If it's not eligible then we can flush it early to allow for it to be inline.
These are now appearing in order (except the "first paint" thing)
3f4d51b
to
8ab5e1f
Compare
} | ||
|
||
// @gate enableSuspenseList | ||
it('shows content independently by default', async () => { |
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.
Is there a difference between a default SuspenseList
and just wrapping it with a Fragment
?
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.
I don't think so but I always forget the special cases for updates that affect nested SuspenseList.
I forget that the default doesn't do anything a lot but basically you probably always should pick some options. We could make it a required props. It's mainly useful to disable conditionally. However, we don't really an option other than undefined
. I've been thinking that maybe should add "independent"
as an option for that case.
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 case is a bit interesting:
react/packages/react-reconciler/src/__tests__/ReactSuspenseList-test.js
Lines 578 to 585 in a3abf5f
<SuspenseList> | |
<Suspense fallback={<Text text="Loading B" />}> | |
<B /> | |
</Suspense> | |
<Suspense fallback={<Text text="Loading C" />}> | |
<C /> | |
</Suspense> | |
</SuspenseList> |
It's a case where because the outer one is in "together"
mode, it blocks the inner ones from revealing independently. That's the same as if it was a Fragment so I think it's the same.
However, if the inner one had an explicit "independent"
string, shouldn't that override the outer "together"
mode?
componentStack: null | ComponentStackNode, // stack frame description of the currently rendering component | ||
thenableState: null | ThenableState, | ||
legacyContext: LegacyContext, // the current legacy context that this task is executing in | ||
debugTask: null | ConsoleTask, // DEV only | ||
// DON'T ANY MORE FIELDS. We at 16 already which otherwise requires converting to a constructor. | ||
// DON'T ANY MORE FIELDS. We at 16 in prod already which otherwise requires converting to a constructor. |
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.
Aren't we at 17 now?
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.
I'm not counting legacyContext
.
Typo Co-authored-by: Sebastian "Sebbie" Silbermann <silbermann.sebastian@gmail.com>
) Basically we track a `SuspenseListRow` on the task. These keep track of "pending tasks" that block the row. A row is blocked by: - First itself completing rendering. - A previous row completing. - Any tasks inside the row and before the Suspense boundary inside the row. This is mainly because we don't yet know if we'll discover more SuspenseBoundaries. - Previous row's SuspenseBoundaries completing. If a boundary might get outlined, then we can't consider it completed until we have written it because it determined whether other future boundaries in the row can finish. This is just handling basic semantics. Features not supported yet that need follow ups later: - CSS dependencies of previous rows should be added as dependencies of future row's suspense boundary. Because otherwise if the client is blocked on CSS then a previous row could be blocked but the server doesn't know it. - I need a second pass on nested SuspenseList semantics. - `revealOrder="together"` - `tail="hidden"`/`tail="collapsed"`. This needs some new runtime semantics to the Fizz runtime and to allow the hydration to handle missing rows in the HTML. This should also be future compatible with AsyncIterable where we don't know how many rows upfront. - Need to double check resuming semantics. --------- Co-authored-by: Sebastian "Sebbie" Silbermann <silbermann.sebastian@gmail.com> DiffTrain build for [5dc1b21](5dc1b21)
Follow up to #33306. If we're nested inside a SuspenseList and we have a row, then we can point our last row to block the parent row and unblock the parent when the last child unblocks.
Basically we track a
SuspenseListRow
on the task. These keep track of "pending tasks" that block the row. A row is blocked by:If a boundary might get outlined, then we can't consider it completed until we have written it because it determined whether other future boundaries in the row can finish.
This is just handling basic semantics. Features not supported yet that need follow ups later:
revealOrder="together"
. [Fizz] Support SuspenseList revealOrder="together" #33311.tail="hidden"
/tail="collapsed"
. This needs some new runtime semantics to the Fizz runtime and to allow the hydration to handle missing rows in the HTML. This should also be future compatible with AsyncIterable where we don't know how many rows upfront.