-
Notifications
You must be signed in to change notification settings - Fork 47.3k
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
[Fiber] Highlight hydration and offscreen render phases #31752
Conversation
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
Comparing: d5e8f79...1cdf20f Critical size changesIncludes critical production bundles, as well as any change greater than 2%:
Significant size changesIncludes any change greater than 0.2%: (No significant changes) |
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 is sick, i like green and eventually red as signals and the naming.
Taking a mental note that when we ship this we'll want to have DevTools docs with the names of these things documented so people understand the concepts
Related to #31752. When hydrating, we have two different ways of handling a Suspense boundary that the server has already given up on and decided to client render. If we have already hydrated the parent and then later this happens, then we'll use the retry lane like any ping. If we discover that it was already in client-render mode when we discover the Suspense boundary for the first time, then schedule a default lane to let us first finish the current render and then upgrade the priority to sync to try to client render this boundary as soon as possible since we're holding back content. We used to use the `DefaultHydrationLane` for this but this is not really a Hydration. It's actually a client render. If we get any other updates flowing in from above at the same time we might as well do them in the same pass instead of two passes. So this should be considered more like any update. This also means that visually the client render pass now gets painted as a render instead of a hydration. This show the flow of a shell being hydrated at the default priority, then a Suspense boundary being discovered and hydrated at Idle and then an inner boundary being discovered as client rendered which gets upgraded to default. <img width="1363" alt="Screenshot 2024-12-14 at 12 13 57 AM" src="https://github.com/user-attachments/assets/a141133e-4856-4f38-a11f-f26bd00b6245" />
I was also planning to add info in the details pane and the tooltip explaining more what this means. One unfortunate thing is that the colors are different from the React DevTools profiler. Partly because we're limited in the colors we're allowed to use but also because we're showing more dimensions of data here.
|
Related to #31752. When hydrating, we have two different ways of handling a Suspense boundary that the server has already given up on and decided to client render. If we have already hydrated the parent and then later this happens, then we'll use the retry lane like any ping. If we discover that it was already in client-render mode when we discover the Suspense boundary for the first time, then schedule a default lane to let us first finish the current render and then upgrade the priority to sync to try to client render this boundary as soon as possible since we're holding back content. We used to use the `DefaultHydrationLane` for this but this is not really a Hydration. It's actually a client render. If we get any other updates flowing in from above at the same time we might as well do them in the same pass instead of two passes. So this should be considered more like any update. This also means that visually the client render pass now gets painted as a render instead of a hydration. This show the flow of a shell being hydrated at the default priority, then a Suspense boundary being discovered and hydrated at Idle and then an inner boundary being discovered as client rendered which gets upgraded to default. <img width="1363" alt="Screenshot 2024-12-14 at 12 13 57 AM" src="https://github.com/user-attachments/assets/a141133e-4856-4f38-a11f-f26bd00b6245" /> DiffTrain build for [d1dd7fe](d1dd7fe)
Related to #31752. When hydrating, we have two different ways of handling a Suspense boundary that the server has already given up on and decided to client render. If we have already hydrated the parent and then later this happens, then we'll use the retry lane like any ping. If we discover that it was already in client-render mode when we discover the Suspense boundary for the first time, then schedule a default lane to let us first finish the current render and then upgrade the priority to sync to try to client render this boundary as soon as possible since we're holding back content. We used to use the `DefaultHydrationLane` for this but this is not really a Hydration. It's actually a client render. If we get any other updates flowing in from above at the same time we might as well do them in the same pass instead of two passes. So this should be considered more like any update. This also means that visually the client render pass now gets painted as a render instead of a hydration. This show the flow of a shell being hydrated at the default priority, then a Suspense boundary being discovered and hydrated at Idle and then an inner boundary being discovered as client rendered which gets upgraded to default. <img width="1363" alt="Screenshot 2024-12-14 at 12 13 57 AM" src="https://github.com/user-attachments/assets/a141133e-4856-4f38-a11f-f26bd00b6245" /> DiffTrain build for [d1dd7fe](d1dd7fe)
This is a follow up to #31752. This keeps track in the commit phase whether this subtree was hydrated. If it was, then we mark those components in the Components track as green. Just like the phase itself is marked as green. If the boundary client rendered we instead mark it as "errored" and its children given the plain primary render color (blue). I also collect the hydration error for this case so we can include its message in the details view. (Unfortunately this doesn't support newlines atm.) Most of the time this happens in separate commits for each boundary but it is possible to force a client render in the same pass as a hydration. Such as if an update flows into a boundary that has been put into fallback state after it was initially attempted. <img width="1487" alt="Screenshot 2024-12-18 at 12 06 54 AM" src="https://github.com/user-attachments/assets/74c57291-4d11-414c-9751-3dac3285a89a" />
This is a follow up to #31752. This keeps track in the commit phase whether this subtree was hydrated. If it was, then we mark those components in the Components track as green. Just like the phase itself is marked as green. If the boundary client rendered we instead mark it as "errored" and its children given the plain primary render color (blue). I also collect the hydration error for this case so we can include its message in the details view. (Unfortunately this doesn't support newlines atm.) Most of the time this happens in separate commits for each boundary but it is possible to force a client render in the same pass as a hydration. Such as if an update flows into a boundary that has been put into fallback state after it was initially attempted. <img width="1487" alt="Screenshot 2024-12-18 at 12 06 54 AM" src="https://github.com/user-attachments/assets/74c57291-4d11-414c-9751-3dac3285a89a" /> DiffTrain build for [17520b6](17520b6)
This is a follow up to #31752. This keeps track in the commit phase whether this subtree was hydrated. If it was, then we mark those components in the Components track as green. Just like the phase itself is marked as green. If the boundary client rendered we instead mark it as "errored" and its children given the plain primary render color (blue). I also collect the hydration error for this case so we can include its message in the details view. (Unfortunately this doesn't support newlines atm.) Most of the time this happens in separate commits for each boundary but it is possible to force a client render in the same pass as a hydration. Such as if an update flows into a boundary that has been put into fallback state after it was initially attempted. <img width="1487" alt="Screenshot 2024-12-18 at 12 06 54 AM" src="https://github.com/user-attachments/assets/74c57291-4d11-414c-9751-3dac3285a89a" /> DiffTrain build for [17520b6](17520b6)
This highlights the render phase as the tertiary color (green) when we're render a hydration lane or offscreen lane.
I call the "Render" phase "Hydrated" instead in this case. For the offscreen case we don't currently have a differentiation between hydrated or activity. I just called that "Prepared". Even for the hydration case where there's no discovered client rendered boundaries it's more like it's preparing for an interaction rather than blocking one. Where as for the other lanes the hydration might block something.
In a follow up I'd like to color the components in the Components tree green if they were hydrated but not the ones that was actually client rendered e.g. due to a mismatch or forced client rendering so you can tell the difference. Unfortunately, the current signals we have for this get reset earlier in the commit phase than when we log these.
Another thing is that a failed hydration should probably be colored red even though it ends up committing successfully. I.e. a recoverable error.