Skip to content
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

[Fizz] Ensure Resumable State is Serializable #27388

Merged
merged 8 commits into from
Sep 20, 2023

Conversation

sebmarkbage
Copy link
Collaborator

@sebmarkbage sebmarkbage commented Sep 18, 2023

Moves writing queues to renderState.

We shouldn't need the resource tracking's value. We just need to know if that resource has already been emitted. We can use a Set for this. To ensure that set is directly serializable we can just use a dictionary-like object with no value.

See individual commits for special cases.

@sebmarkbage sebmarkbage marked this pull request as draft September 18, 2023 02:54
@facebook-github-bot facebook-github-bot added CLA Signed React Core Team Opened by a member of the React Core Team labels Sep 18, 2023
@react-sizebot
Copy link

react-sizebot commented Sep 18, 2023

Comparing: 1b1dcb8...f6d83b1

Critical size changes

Includes critical production bundles, as well as any change greater than 2%:

Name +/- Base Current +/- gzip Base gzip Current gzip
oss-stable/react-dom/cjs/react-dom.production.min.js = 166.62 kB 166.62 kB = 52.13 kB 52.13 kB
oss-experimental/react-dom/cjs/react-dom.production.min.js = 176.05 kB 176.05 kB = 54.97 kB 54.97 kB
facebook-www/ReactDOM-prod.classic.js = 571.73 kB 571.73 kB = 100.64 kB 100.64 kB
facebook-www/ReactDOM-prod.modern.js = 555.46 kB 555.46 kB = 97.75 kB 97.75 kB
facebook-www/ReactDOMServer-prod.classic.js = 178.90 kB 174.75 kB = 31.63 kB 30.94 kB
facebook-www/ReactDOMServer-prod.modern.js = 177.97 kB 173.81 kB = 31.38 kB 30.70 kB

Significant size changes

Includes any change greater than 0.2%:

Expand to show
Name +/- Base Current +/- gzip Base gzip Current gzip
oss-experimental/react-dom/cjs/react-dom-server.browser.production.min.js +0.85% 75.37 kB 76.01 kB +0.63% 22.88 kB 23.02 kB
oss-experimental/react-dom/umd/react-dom-server.browser.production.min.js +0.85% 75.49 kB 76.13 kB +0.84% 23.17 kB 23.37 kB
oss-stable-semver/react-dom/cjs/react-dom-server.browser.production.min.js +0.84% 69.15 kB 69.74 kB +0.69% 21.28 kB 21.43 kB
oss-stable-semver/react-dom/umd/react-dom-server.browser.production.min.js +0.84% 69.29 kB 69.88 kB +0.93% 21.54 kB 21.74 kB
oss-stable/react-dom/cjs/react-dom-server.browser.production.min.js +0.84% 69.18 kB 69.76 kB +0.69% 21.30 kB 21.45 kB
oss-stable/react-dom/umd/react-dom-server.browser.production.min.js +0.84% 69.32 kB 69.90 kB +0.93% 21.56 kB 21.76 kB
oss-stable-semver/react-dom/cjs/react-dom-server.node.production.min.js +0.81% 74.31 kB 74.91 kB +0.69% 22.89 kB 23.05 kB
oss-stable/react-dom/cjs/react-dom-server.node.production.min.js +0.81% 74.34 kB 74.94 kB +0.69% 22.92 kB 23.07 kB
oss-stable-semver/react-dom/cjs/react-dom-server.bun.production.min.js +0.80% 72.38 kB 72.96 kB +0.68% 21.83 kB 21.98 kB
oss-stable/react-dom/cjs/react-dom-server.bun.production.min.js +0.80% 72.40 kB 72.98 kB +0.69% 21.86 kB 22.01 kB
oss-stable-semver/react-dom/cjs/react-dom-server-legacy.browser.development.js +0.80% 371.83 kB 374.81 kB +0.69% 81.11 kB 81.67 kB
oss-stable/react-dom/cjs/react-dom-server-legacy.browser.development.js +0.80% 371.85 kB 374.84 kB +0.69% 81.13 kB 81.69 kB
oss-stable-semver/react-dom/umd/react-dom-server-legacy.browser.development.js +0.80% 389.74 kB 392.85 kB +0.74% 81.98 kB 82.59 kB
oss-stable/react-dom/umd/react-dom-server-legacy.browser.development.js +0.80% 389.77 kB 392.88 kB +0.74% 82.01 kB 82.61 kB
oss-experimental/react-dom/cjs/react-dom-server.edge.production.min.js +0.80% 80.71 kB 81.35 kB +0.66% 24.52 kB 24.68 kB
oss-experimental/react-dom/cjs/react-dom-server.node.production.min.js +0.80% 80.97 kB 81.62 kB +0.70% 24.69 kB 24.87 kB
oss-stable-semver/react-dom/cjs/react-dom-server.edge.production.min.js +0.79% 74.26 kB 74.85 kB +0.64% 22.82 kB 22.97 kB
oss-stable/react-dom/cjs/react-dom-server.edge.production.min.js +0.79% 74.29 kB 74.88 kB +0.64% 22.85 kB 22.99 kB
oss-stable-semver/react-dom/cjs/react-dom-server-legacy.node.development.js +0.78% 373.74 kB 376.67 kB +0.68% 81.57 kB 82.12 kB
oss-stable/react-dom/cjs/react-dom-server-legacy.node.development.js +0.78% 373.76 kB 376.69 kB +0.68% 81.59 kB 82.15 kB
facebook-www/ReactDOMServer-dev.modern.js +0.77% 386.42 kB 389.41 kB +1.04% 83.45 kB 84.32 kB
facebook-www/ReactDOMServer-dev.classic.js +0.76% 393.85 kB 396.83 kB +1.02% 85.09 kB 85.96 kB
oss-experimental/react-dom/cjs/react-dom-server-legacy.browser.development.js +0.76% 393.93 kB 396.91 kB +0.60% 85.74 kB 86.25 kB
oss-experimental/react-dom/cjs/react-dom-server.bun.production.min.js +0.75% 76.95 kB 77.53 kB +0.75% 23.33 kB 23.51 kB
oss-experimental/react-dom/umd/react-dom-server-legacy.browser.development.js +0.75% 412.72 kB 415.82 kB +0.98% 86.77 kB 87.62 kB
oss-experimental/react-dom/cjs/react-dom-server-legacy.node.development.js +0.74% 395.84 kB 398.77 kB +0.59% 86.20 kB 86.71 kB
oss-experimental/react-dom/cjs/react-dom-server.browser.development.js +0.67% 399.79 kB 402.45 kB +0.50% 86.49 kB 86.92 kB
oss-experimental/react-dom/cjs/react-dom-server.edge.development.js +0.66% 400.20 kB 402.86 kB +0.50% 86.61 kB 87.04 kB
oss-experimental/react-dom/cjs/react-dom-server.node.development.js +0.66% 401.08 kB 403.75 kB +0.50% 86.81 kB 87.24 kB
oss-stable-semver/react-dom/cjs/react-dom-server.bun.development.js +0.66% 369.32 kB 371.76 kB +0.56% 80.68 kB 81.13 kB
oss-stable/react-dom/cjs/react-dom-server.bun.development.js +0.66% 369.35 kB 371.79 kB +0.57% 80.70 kB 81.16 kB
oss-experimental/react-dom/umd/react-dom-server.browser.development.js +0.66% 418.87 kB 421.63 kB +0.90% 87.50 kB 88.29 kB
oss-stable-semver/react-dom/cjs/react-dom-server.browser.development.js +0.65% 372.10 kB 374.54 kB +0.55% 81.59 kB 82.04 kB
oss-stable/react-dom/cjs/react-dom-server.browser.development.js +0.65% 372.12 kB 374.56 kB +0.55% 81.62 kB 82.07 kB
oss-stable-semver/react-dom/cjs/react-dom-server.edge.development.js +0.65% 372.51 kB 374.95 kB +0.55% 81.71 kB 82.16 kB
oss-stable/react-dom/cjs/react-dom-server.edge.development.js +0.65% 372.53 kB 374.97 kB +0.55% 81.74 kB 82.19 kB
oss-stable-semver/react-dom/cjs/react-dom-server.node.development.js +0.65% 373.58 kB 376.01 kB +0.56% 81.61 kB 82.07 kB
oss-stable/react-dom/cjs/react-dom-server.node.development.js +0.65% 373.60 kB 376.04 kB +0.55% 81.64 kB 82.10 kB
oss-stable-semver/react-dom/umd/react-dom-server.browser.development.js +0.65% 390.02 kB 392.55 kB +0.63% 82.46 kB 82.98 kB
oss-stable/react-dom/umd/react-dom-server.browser.development.js +0.65% 390.04 kB 392.58 kB +0.63% 82.49 kB 83.01 kB
facebook-www/ReactDOMServerStreaming-dev.modern.js +0.65% 381.61 kB 384.09 kB +0.93% 82.29 kB 83.06 kB
oss-experimental/react-dom/cjs/react-dom-server.bun.development.js +0.62% 391.43 kB 393.86 kB +0.49% 85.30 kB 85.72 kB
oss-stable-semver/react-server/cjs/react-server.production.min.js +0.37% 33.92 kB 34.04 kB +0.24% 10.68 kB 10.70 kB
oss-stable/react-server/cjs/react-server.production.min.js +0.37% 33.92 kB 34.04 kB +0.24% 10.68 kB 10.70 kB
oss-experimental/react-server/cjs/react-server.production.min.js +0.34% 36.95 kB 37.07 kB +0.18% 11.57 kB 11.59 kB
facebook-www/ReactDOMServerStreaming-prod.modern.js +0.20% 181.80 kB 182.16 kB +0.40% 32.61 kB 32.74 kB
oss-experimental/react-dom/cjs/react-dom-server-legacy.node.production.min.js = 78.52 kB 77.38 kB = 23.63 kB 23.31 kB
oss-experimental/react-dom/umd/react-dom-server-legacy.browser.production.min.js = 72.62 kB 71.51 kB = 22.16 kB 21.81 kB
oss-experimental/react-dom/cjs/react-dom-server-legacy.browser.production.min.js = 72.47 kB 71.36 kB = 21.81 kB 21.47 kB
oss-stable/react-dom/cjs/react-dom-server-legacy.node.production.min.js = 73.97 kB 72.84 kB = 22.14 kB 21.82 kB
oss-stable-semver/react-dom/cjs/react-dom-server-legacy.node.production.min.js = 73.95 kB 72.81 kB = 22.11 kB 21.80 kB
oss-stable/react-dom/umd/react-dom-server-legacy.browser.production.min.js = 68.33 kB 67.23 kB = 20.67 kB 20.35 kB
oss-stable-semver/react-dom/umd/react-dom-server-legacy.browser.production.min.js = 68.30 kB 67.20 kB = 20.65 kB 20.32 kB
oss-stable/react-dom/cjs/react-dom-server-legacy.browser.production.min.js = 68.17 kB 67.07 kB = 20.36 kB 20.00 kB
oss-stable-semver/react-dom/cjs/react-dom-server-legacy.browser.production.min.js = 68.14 kB 67.04 kB = 20.34 kB 19.97 kB
facebook-www/ReactDOMServer-prod.classic.js = 178.90 kB 174.75 kB = 31.63 kB 30.94 kB
facebook-www/ReactDOMServer-prod.modern.js = 177.97 kB 173.81 kB = 31.38 kB 30.70 kB

Generated by 🚫 dangerJS against f6d83b1

@sebmarkbage sebmarkbage force-pushed the serializablestate branch 2 times, most recently from 7e58de5 to d14b721 Compare September 18, 2023 03:18
@@ -152,6 +152,7 @@ export type RenderState = {
fontPreloads: Set<PreloadResource>,
highImagePreloads: Set<PreloadResource>,
// usedImagePreloads: Set<PreloadResource>,
// TODO: Precedences needs to be seeded with the order of precedence after resuming.
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gnoff Is it necessary for this to be in order after the shell flushes? Because afterwards we just insert relative to existing ones, right? So the order doesn't matter anymore.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is correct. we'd only need to reconstruct the right order when we support preamble only and want to resume the shell

const resourceProps = stylesheetPropsFromRawProps(props);
const preloadResource = resumableState.preloadsMap.get(key);
const preloadResource = resumableState.preloadsMap.get(key); // TODO
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The preload map tracks state which we might need.

@@ -2182,7 +2182,7 @@ function pushLink(
precedenceSet.add(resource);
}
if (renderState.boundaryResources) {
renderState.boundaryResources.add(resource);
renderState.boundaryResources.add(resource); // TODO
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gnoff Do we need to be able to transfer this to the boundary? We might not need to track them across resuming if assume that they're always flushed in the shell. We might need to keep track of them during a single render pass. Like if we the same resource is discovered in a different boundary which then gets completed first.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need to track across resuming b/c all style resources should flush with the shell. But within the resume render we still need to track this association b/c the first boundary to complete that depends on this resource needs to create it as part of the reveal instruction and that could be a different boundary than the one that first observed it. (I think this is what you are saying but not sure so I'm restating it)

pushStyleContents(resource.chunks, props);
}
if (renderState.boundaryResources) {
renderState.boundaryResources.add(resource); // TODO
}
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gnoff I moved this out because it appears to be inconsistent with stylesheet. Either we have to add it to boundary resources each time it's discovered or maybe not all.

If we don't need this to be coordinated because it's always sync available and will always flush early, then maybe we never add it to boundaryResources but if we need it to be emitted, then it seems like we must always add it.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I think this was just my mistake. however, we should reconcider whether it makes sense to hold back some style tags when completing boundaries vs just flushing everything we've accumulated so far. If we always flush all style precedences on each tick then we don't need to track

@sebmarkbage sebmarkbage force-pushed the serializablestate branch 2 times, most recently from 30539e6 to 60f646e Compare September 19, 2023 23:48
@sebmarkbage sebmarkbage marked this pull request as ready for review September 19, 2023 23:50
precedenceSet.add(resource);
renderState.stylePrecedences.set(precedence, resource);
const stylesInPrecedence: Map<string, StyleResource> = new Map();
stylesInPrecedence.set(key, resource);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for consistency the key should probably be '' here to match the empty style resource created upon a new precedence in pushLink and preinitStyle. The resource isn't really keyed by this key uniquely since it will accumulate contents from many keys

Bootstrapscripts, external runtime and resource queues are all expected
to flush in the prerender. They're only needed by the prerender and then
they can get dropped/reset.

Threfore we can move them to the renderState.
We need some way to look up an existing resource to add it to boundary
resources, if it still isn't flushed.

Since style tags are 1:1 with precedence, we can just use the precedence
to get it.

Since we can't get stylesheet resources from stylesMap anymore we have to
get it from somewhere and we already have it on the precedence list. We'd
just need to iterate to find it and even then we don't have it by key.

So I just turn the Set into a Map so we can get it from there.
We have to ensure these are serializable.

We transfer them to the resume so that they can be applied to resources
discovered during the resume.
@sebmarkbage sebmarkbage merged commit b775564 into facebook:main Sep 20, 2023
2 checks passed
github-actions bot pushed a commit that referenced this pull request Sep 20, 2023
Moves writing queues to renderState.

We shouldn't need the resource tracking's value. We just need to know if
that resource has already been emitted. We can use a Set for this. To
ensure that set is directly serializable we can just use a
dictionary-like object with no value.

See individual commits for special cases.

DiffTrain build for [b775564](b775564)
EdisonVan pushed a commit to EdisonVan/react that referenced this pull request Apr 15, 2024
Moves writing queues to renderState.

We shouldn't need the resource tracking's value. We just need to know if
that resource has already been emitted. We can use a Set for this. To
ensure that set is directly serializable we can just use a
dictionary-like object with no value.

See individual commits for special cases.
bigfootjon pushed a commit that referenced this pull request Apr 18, 2024
Moves writing queues to renderState.

We shouldn't need the resource tracking's value. We just need to know if
that resource has already been emitted. We can use a Set for this. To
ensure that set is directly serializable we can just use a
dictionary-like object with no value.

See individual commits for special cases.

DiffTrain build for commit b775564.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CLA Signed React Core Team Opened by a member of the React Core Team
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants