Skip to content

[Flight] Parse Stack Trace from Structured CallSite if available #33135

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

Merged
merged 2 commits into from
May 7, 2025

Conversation

sebmarkbage
Copy link
Collaborator

@sebmarkbage sebmarkbage commented May 7, 2025

This is first step to include more enclosing line/column in the parsed data.

We install our own prepareStackTrace to collect structured callsite data and only fall back to parsing the string if it was already evaluated or if prepareStackTrace doesn't work in this environment.

We still mirror the default V8 format for encoding the function name part. A lot of this is covered by tests already.

@sebmarkbage sebmarkbage requested a review from eps1lon May 7, 2025 01:13
@github-actions github-actions bot added the React Core Team Opened by a member of the React Core Team label May 7, 2025
@react-sizebot
Copy link

react-sizebot commented May 7, 2025

Comparing: e5a8de8...dd0eaba

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.js = 6.68 kB 6.68 kB = 1.83 kB 1.83 kB
oss-stable/react-dom/cjs/react-dom-client.production.js = 528.26 kB 528.29 kB = 93.16 kB 93.15 kB
oss-experimental/react-dom/cjs/react-dom.production.js = 6.69 kB 6.69 kB = 1.83 kB 1.83 kB
oss-experimental/react-dom/cjs/react-dom-client.production.js = 645.02 kB 638.61 kB = 113.47 kB 112.15 kB
facebook-www/ReactDOM-prod.classic.js = 673.72 kB 667.31 kB = 118.32 kB 116.98 kB
facebook-www/ReactDOM-prod.modern.js = 664.00 kB 657.59 kB = 116.73 kB 115.43 kB
oss-stable-semver/react-server/cjs/react-server-flight.development.js +3.07% 101.64 kB 104.76 kB +3.54% 18.89 kB 19.55 kB
oss-stable/react-server/cjs/react-server-flight.development.js +3.07% 101.64 kB 104.76 kB +3.54% 18.89 kB 19.55 kB
oss-experimental/react-server/cjs/react-server-flight.development.js +2.88% 108.47 kB 111.59 kB +3.34% 20.08 kB 20.75 kB
oss-stable-semver/react-server-dom-parcel/cjs/react-server-dom-parcel-server.browser.development.js +2.22% 140.52 kB 143.65 kB +2.65% 26.10 kB 26.79 kB
oss-stable/react-server-dom-parcel/cjs/react-server-dom-parcel-server.browser.development.js +2.22% 140.52 kB 143.65 kB +2.65% 26.10 kB 26.79 kB
oss-stable-semver/react-server-dom-parcel/cjs/react-server-dom-parcel-server.edge.development.js +2.16% 144.35 kB 147.46 kB +2.44% 26.73 kB 27.38 kB
oss-stable/react-server-dom-parcel/cjs/react-server-dom-parcel-server.edge.development.js +2.16% 144.35 kB 147.46 kB +2.44% 26.73 kB 27.38 kB
oss-stable-semver/react-server-dom-esm/cjs/react-server-dom-esm-server.node.development.js +2.15% 144.93 kB 148.05 kB +2.37% 27.00 kB 27.64 kB
oss-stable/react-server-dom-esm/cjs/react-server-dom-esm-server.node.development.js +2.15% 144.93 kB 148.05 kB +2.37% 27.00 kB 27.64 kB
oss-stable-semver/react-server-dom-parcel/cjs/react-server-dom-parcel-server.node.development.js +2.15% 144.96 kB 148.07 kB +2.37% 26.97 kB 27.61 kB
oss-stable/react-server-dom-parcel/cjs/react-server-dom-parcel-server.node.development.js +2.15% 144.96 kB 148.07 kB +2.37% 26.97 kB 27.61 kB
oss-experimental/react-server-dom-parcel/cjs/react-server-dom-parcel-server.browser.development.js +2.12% 147.37 kB 150.49 kB +2.57% 27.28 kB 27.99 kB
oss-stable-semver/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.browser.development.js +2.11% 148.26 kB 151.39 kB +2.53% 27.41 kB 28.11 kB
oss-stable/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.browser.development.js +2.11% 148.26 kB 151.39 kB +2.53% 27.41 kB 28.11 kB
oss-stable-semver/react-server-dom-webpack/cjs/react-server-dom-webpack-server.browser.development.js +2.10% 148.81 kB 151.93 kB +2.52% 27.54 kB 28.24 kB
oss-stable/react-server-dom-webpack/cjs/react-server-dom-webpack-server.browser.development.js +2.10% 148.81 kB 151.93 kB +2.52% 27.54 kB 28.24 kB
oss-stable-semver/react-server-dom-webpack/cjs/react-server-dom-webpack-server.node.unbundled.development.js +2.05% 151.63 kB 154.74 kB +2.46% 28.04 kB 28.73 kB
oss-stable/react-server-dom-webpack/cjs/react-server-dom-webpack-server.node.unbundled.development.js +2.05% 151.63 kB 154.74 kB +2.46% 28.04 kB 28.73 kB
oss-experimental/react-server-dom-parcel/cjs/react-server-dom-parcel-server.edge.development.js +2.05% 151.83 kB 154.94 kB +2.40% 28.01 kB 28.68 kB
oss-experimental/react-server-dom-esm/cjs/react-server-dom-esm-server.node.development.js +2.05% 152.07 kB 155.19 kB +2.46% 28.26 kB 28.96 kB
oss-experimental/react-server-dom-parcel/cjs/react-server-dom-parcel-server.node.development.js +2.05% 152.10 kB 155.21 kB +2.41% 28.28 kB 28.96 kB
oss-stable-semver/react-server-dom-webpack/cjs/react-server-dom-webpack-server.edge.development.js +2.05% 152.10 kB 155.21 kB +2.43% 28.05 kB 28.73 kB
oss-stable/react-server-dom-webpack/cjs/react-server-dom-webpack-server.edge.development.js +2.05% 152.10 kB 155.21 kB +2.43% 28.05 kB 28.73 kB
oss-stable-semver/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.edge.development.js +2.05% 152.13 kB 155.24 kB +2.43% 28.04 kB 28.72 kB
oss-stable/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.edge.development.js +2.05% 152.13 kB 155.24 kB +2.43% 28.04 kB 28.72 kB
oss-stable-semver/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.node.development.js +2.04% 152.77 kB 155.88 kB +2.40% 28.32 kB 29.00 kB
oss-stable/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.node.development.js +2.04% 152.77 kB 155.88 kB +2.40% 28.32 kB 29.00 kB
oss-stable-semver/react-server-dom-webpack/cjs/react-server-dom-webpack-server.node.development.js +2.04% 152.83 kB 155.95 kB +2.41% 28.34 kB 29.02 kB
oss-stable/react-server-dom-webpack/cjs/react-server-dom-webpack-server.node.development.js +2.04% 152.83 kB 155.95 kB +2.41% 28.34 kB 29.02 kB
oss-experimental/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.browser.development.js +2.01% 155.11 kB 158.23 kB +2.47% 28.66 kB 29.36 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-server.browser.development.js +2.01% 155.65 kB 158.78 kB +2.45% 28.78 kB 29.49 kB
oss-experimental/react-reconciler/cjs/react-reconciler-reflection.production.js = 9.91 kB 6.54 kB = 2.39 kB 1.69 kB
oss-stable-semver/react-reconciler/cjs/react-reconciler-reflection.production.js = 9.91 kB 6.54 kB = 2.39 kB 1.69 kB
oss-stable/react-reconciler/cjs/react-reconciler-reflection.production.js = 9.91 kB 6.54 kB = 2.39 kB 1.69 kB
oss-experimental/react-reconciler/cjs/react-reconciler-reflection.development.js = 11.25 kB 7.22 kB = 2.45 kB 1.69 kB
oss-stable-semver/react-reconciler/cjs/react-reconciler-reflection.development.js = 11.25 kB 7.22 kB = 2.45 kB 1.69 kB
oss-stable/react-reconciler/cjs/react-reconciler-reflection.development.js = 11.25 kB 7.22 kB = 2.45 kB 1.69 kB

Significant size changes

Includes any change greater than 0.2%:

Expand to show
Name +/- Base Current +/- gzip Base gzip Current gzip
oss-stable-semver/react-server/cjs/react-server-flight.development.js +3.07% 101.64 kB 104.76 kB +3.54% 18.89 kB 19.55 kB
oss-stable/react-server/cjs/react-server-flight.development.js +3.07% 101.64 kB 104.76 kB +3.54% 18.89 kB 19.55 kB
oss-experimental/react-server/cjs/react-server-flight.development.js +2.88% 108.47 kB 111.59 kB +3.34% 20.08 kB 20.75 kB
oss-stable-semver/react-server-dom-parcel/cjs/react-server-dom-parcel-server.browser.development.js +2.22% 140.52 kB 143.65 kB +2.65% 26.10 kB 26.79 kB
oss-stable/react-server-dom-parcel/cjs/react-server-dom-parcel-server.browser.development.js +2.22% 140.52 kB 143.65 kB +2.65% 26.10 kB 26.79 kB
oss-stable-semver/react-server-dom-parcel/cjs/react-server-dom-parcel-server.edge.development.js +2.16% 144.35 kB 147.46 kB +2.44% 26.73 kB 27.38 kB
oss-stable/react-server-dom-parcel/cjs/react-server-dom-parcel-server.edge.development.js +2.16% 144.35 kB 147.46 kB +2.44% 26.73 kB 27.38 kB
oss-stable-semver/react-server-dom-esm/cjs/react-server-dom-esm-server.node.development.js +2.15% 144.93 kB 148.05 kB +2.37% 27.00 kB 27.64 kB
oss-stable/react-server-dom-esm/cjs/react-server-dom-esm-server.node.development.js +2.15% 144.93 kB 148.05 kB +2.37% 27.00 kB 27.64 kB
oss-stable-semver/react-server-dom-parcel/cjs/react-server-dom-parcel-server.node.development.js +2.15% 144.96 kB 148.07 kB +2.37% 26.97 kB 27.61 kB
oss-stable/react-server-dom-parcel/cjs/react-server-dom-parcel-server.node.development.js +2.15% 144.96 kB 148.07 kB +2.37% 26.97 kB 27.61 kB
oss-experimental/react-server-dom-parcel/cjs/react-server-dom-parcel-server.browser.development.js +2.12% 147.37 kB 150.49 kB +2.57% 27.28 kB 27.99 kB
oss-stable-semver/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.browser.development.js +2.11% 148.26 kB 151.39 kB +2.53% 27.41 kB 28.11 kB
oss-stable/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.browser.development.js +2.11% 148.26 kB 151.39 kB +2.53% 27.41 kB 28.11 kB
oss-stable-semver/react-server-dom-webpack/cjs/react-server-dom-webpack-server.browser.development.js +2.10% 148.81 kB 151.93 kB +2.52% 27.54 kB 28.24 kB
oss-stable/react-server-dom-webpack/cjs/react-server-dom-webpack-server.browser.development.js +2.10% 148.81 kB 151.93 kB +2.52% 27.54 kB 28.24 kB
oss-stable-semver/react-server-dom-webpack/cjs/react-server-dom-webpack-server.node.unbundled.development.js +2.05% 151.63 kB 154.74 kB +2.46% 28.04 kB 28.73 kB
oss-stable/react-server-dom-webpack/cjs/react-server-dom-webpack-server.node.unbundled.development.js +2.05% 151.63 kB 154.74 kB +2.46% 28.04 kB 28.73 kB
oss-experimental/react-server-dom-parcel/cjs/react-server-dom-parcel-server.edge.development.js +2.05% 151.83 kB 154.94 kB +2.40% 28.01 kB 28.68 kB
oss-experimental/react-server-dom-esm/cjs/react-server-dom-esm-server.node.development.js +2.05% 152.07 kB 155.19 kB +2.46% 28.26 kB 28.96 kB
oss-experimental/react-server-dom-parcel/cjs/react-server-dom-parcel-server.node.development.js +2.05% 152.10 kB 155.21 kB +2.41% 28.28 kB 28.96 kB
oss-stable-semver/react-server-dom-webpack/cjs/react-server-dom-webpack-server.edge.development.js +2.05% 152.10 kB 155.21 kB +2.43% 28.05 kB 28.73 kB
oss-stable/react-server-dom-webpack/cjs/react-server-dom-webpack-server.edge.development.js +2.05% 152.10 kB 155.21 kB +2.43% 28.05 kB 28.73 kB
oss-stable-semver/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.edge.development.js +2.05% 152.13 kB 155.24 kB +2.43% 28.04 kB 28.72 kB
oss-stable/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.edge.development.js +2.05% 152.13 kB 155.24 kB +2.43% 28.04 kB 28.72 kB
oss-stable-semver/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.node.development.js +2.04% 152.77 kB 155.88 kB +2.40% 28.32 kB 29.00 kB
oss-stable/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.node.development.js +2.04% 152.77 kB 155.88 kB +2.40% 28.32 kB 29.00 kB
oss-stable-semver/react-server-dom-webpack/cjs/react-server-dom-webpack-server.node.development.js +2.04% 152.83 kB 155.95 kB +2.41% 28.34 kB 29.02 kB
oss-stable/react-server-dom-webpack/cjs/react-server-dom-webpack-server.node.development.js +2.04% 152.83 kB 155.95 kB +2.41% 28.34 kB 29.02 kB
oss-experimental/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.browser.development.js +2.01% 155.11 kB 158.23 kB +2.47% 28.66 kB 29.36 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-server.browser.development.js +2.01% 155.65 kB 158.78 kB +2.45% 28.78 kB 29.49 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-server.node.unbundled.development.js +1.96% 158.77 kB 161.88 kB +2.23% 29.35 kB 30.00 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-server.edge.development.js +1.95% 159.58 kB 162.69 kB +2.16% 29.39 kB 30.02 kB
oss-experimental/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.edge.development.js +1.95% 159.61 kB 162.72 kB +2.17% 29.38 kB 30.02 kB
oss-experimental/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.node.development.js +1.95% 159.91 kB 163.02 kB +2.21% 29.63 kB 30.29 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-server.node.development.js +1.95% 159.97 kB 163.09 kB +2.21% 29.64 kB 30.30 kB
oss-experimental/react-markup/cjs/react-markup.react-server.development.js +0.57% 538.44 kB 541.51 kB +0.65% 96.57 kB 97.19 kB
facebook-www/ReactDOMTesting-dev.classic.js = 1,240.12 kB 1,232.60 kB = 205.78 kB 204.32 kB
facebook-www/ReactDOMTesting-dev.modern.js = 1,230.98 kB 1,223.46 kB = 204.05 kB 202.61 kB
facebook-www/ReactDOM-dev.classic.js = 1,223.59 kB 1,216.07 kB = 202.06 kB 200.63 kB
facebook-www/ReactDOM-dev.modern.js = 1,214.44 kB 1,206.92 kB = 200.31 kB 198.85 kB
oss-experimental/react-dom/cjs/react-dom-unstable_testing.development.js = 1,181.60 kB 1,174.08 kB = 197.38 kB 195.92 kB
oss-experimental/react-dom/cjs/react-dom-profiling.development.js = 1,181.45 kB 1,173.93 kB = 196.53 kB 195.07 kB
oss-experimental/react-dom/cjs/react-dom-client.development.js = 1,165.06 kB 1,157.54 kB = 193.69 kB 192.22 kB
facebook-react-native/react-dom/cjs/ReactDOMProfiling-dev.js = 1,049.18 kB 1,041.66 kB = 176.05 kB 174.63 kB
facebook-react-native/react-dom/cjs/ReactDOMClient-dev.js = 1,032.85 kB 1,025.33 kB = 173.24 kB 171.82 kB
facebook-www/ReactDOM-profiling.classic.js = 743.38 kB 736.97 kB = 127.67 kB 126.36 kB
facebook-www/ReactDOM-profiling.modern.js = 735.34 kB 728.93 kB = 126.38 kB 125.08 kB
oss-experimental/react-dom/cjs/react-dom-profiling.profiling.js = 707.18 kB 700.76 kB = 122.52 kB 121.19 kB
facebook-www/ReactDOMTesting-prod.classic.js = 688.13 kB 681.71 kB = 121.96 kB 120.68 kB
facebook-www/ReactDOMTesting-prod.modern.js = 678.41 kB 671.99 kB = 120.37 kB 119.08 kB
facebook-www/ReactDOM-prod.classic.js = 673.72 kB 667.31 kB = 118.32 kB 116.98 kB
facebook-www/ReactDOM-prod.modern.js = 664.00 kB 657.59 kB = 116.73 kB 115.43 kB
oss-experimental/react-dom/cjs/react-dom-unstable_testing.production.js = 659.43 kB 653.02 kB = 117.01 kB 115.72 kB
oss-experimental/react-dom/cjs/react-dom-client.production.js = 645.02 kB 638.61 kB = 113.47 kB 112.15 kB
facebook-react-native/react-dom/cjs/ReactDOMProfiling-profiling.js = 608.97 kB 602.55 kB = 106.43 kB 105.18 kB
facebook-react-native/react-dom/cjs/ReactDOMClient-profiling.js = 603.02 kB 596.61 kB = 105.29 kB 104.02 kB
facebook-react-native/react-dom/cjs/ReactDOMProfiling-prod.js = 580.33 kB 573.92 kB = 102.34 kB 101.10 kB
facebook-react-native/react-dom/cjs/ReactDOMClient-prod.js = 574.83 kB 568.41 kB = 101.25 kB 100.00 kB
oss-experimental/react-reconciler/cjs/react-reconciler-reflection.production.js = 9.91 kB 6.54 kB = 2.39 kB 1.69 kB
oss-stable-semver/react-reconciler/cjs/react-reconciler-reflection.production.js = 9.91 kB 6.54 kB = 2.39 kB 1.69 kB
oss-stable/react-reconciler/cjs/react-reconciler-reflection.production.js = 9.91 kB 6.54 kB = 2.39 kB 1.69 kB
oss-experimental/react-reconciler/cjs/react-reconciler-reflection.development.js = 11.25 kB 7.22 kB = 2.45 kB 1.69 kB
oss-stable-semver/react-reconciler/cjs/react-reconciler-reflection.development.js = 11.25 kB 7.22 kB = 2.45 kB 1.69 kB
oss-stable/react-reconciler/cjs/react-reconciler-reflection.development.js = 11.25 kB 7.22 kB = 2.45 kB 1.69 kB

Generated by 🚫 dangerJS against dd0eaba

Since we can only trigger prepareStackFrame once, it's important to cache
this since the second time it gets accessed we won't be able to get to it.
}
// At the same time we generate a string stack trace just in case someone
// else reads it. Ideally, we'd call the previous prepareStackTrace to
Copy link
Collaborator

Choose a reason for hiding this comment

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

We might have to call the previous one regardless in case the previous one is a custom one that also contains side-effects. Or do that in Next.js depending on the timing. The tricky bit is figuring how if that's the native one we want to avoid because it would be wasteful to call that.

return String(error.stack);
} finally {
Error.prepareStackTrace = previousPrepare;
const identifierRegExp = /^[a-zA-Z_$][0-9a-zA-Z_$]*$/;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why do we need to test that? Asking because people already complain that our lint rules don't allow unicode characters in Component names so this may come up again here.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I'm trying to mirror what V8 does as much as possible so we get the same from parsing and not.

https://github.com/v8/v8/blob/main/src/objects/call-site-info.cc#L767

However, I didn't dig into what isIdentifier does since you get lost in codegen. I just saw others do this. Usually what I do is this:

https://github.com/facebook/react/blob/main/packages/react-reconciler/src/ReactFiberHydrationDiffs.js#L212-L213

@sebmarkbage sebmarkbage merged commit 0ff1d13 into facebook:main May 7, 2025
239 checks passed
github-actions bot pushed a commit that referenced this pull request May 7, 2025
)

This is first step to include more enclosing line/column in the parsed
data.

We install our own `prepareStackTrace` to collect structured callsite
data and only fall back to parsing the string if it was already
evaluated or if `prepareStackTrace` doesn't work in this environment.

We still mirror the default V8 format for encoding the function name
part. A lot of this is covered by tests already.

DiffTrain build for [0ff1d13](0ff1d13)
sebmarkbage added a commit that referenced this pull request May 7, 2025
… fake function (#33136)

Stacked on #33135.

This encodes the line/column of the enclosing function as part of the
stack traces. When that information is available.

I adjusted the fake function code generation so that the beginning of
the arrow function aligns with these as much as possible.

This ensures that when the browser tries to look up the line/column of
the enclosing function, such as for getting the function name, it gets
the right one. If we can't get the enclosing line/column, then we encode
it at the beginning of the file. This is likely to get a miss in the
source map identifiers, which means that the function name gets
extracted from the runtime name instead which is better.

Another thing where this is used is the in the Performance Track.
Ideally that would be fixed by
https://issues.chromium.org/u/1/issues/415968771 but the enclosing
information is useful for other things like the function name resolution
anyway.

We can also use this for the "View source for this element" in React
DevTools.
github-actions bot pushed a commit that referenced this pull request May 7, 2025
… fake function (#33136)

Stacked on #33135.

This encodes the line/column of the enclosing function as part of the
stack traces. When that information is available.

I adjusted the fake function code generation so that the beginning of
the arrow function aligns with these as much as possible.

This ensures that when the browser tries to look up the line/column of
the enclosing function, such as for getting the function name, it gets
the right one. If we can't get the enclosing line/column, then we encode
it at the beginning of the file. This is likely to get a miss in the
source map identifiers, which means that the function name gets
extracted from the runtime name instead which is better.

Another thing where this is used is the in the Performance Track.
Ideally that would be fixed by
https://issues.chromium.org/u/1/issues/415968771 but the enclosing
information is useful for other things like the function name resolution
anyway.

We can also use this for the "View source for this element" in React
DevTools.

DiffTrain build for [4a70286](4a70286)
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