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

refactor[react-devtools/fiber/renderer]: optimize durations resolution #31118

Merged

Conversation

hoxyq
Copy link
Contributor

@hoxyq hoxyq commented Oct 4, 2024

Stacked on #31117.

No need for sending long float numbers and to have resolution less than a microsecond, we end up formatting it on a Frontend side:

export const formatDuration = (duration: number): number | string =>
Math.round(duration * 10) / 10 || '<0.1';

Copy link

vercel bot commented Oct 4, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
react-compiler-playground ✅ Ready (Inspect) Visit Preview 💬 Add feedback Oct 4, 2024 4:00pm

Comment on lines +5093 to +5104
duration:
formatDurationToMicrosecondsGranularity(maxActualDuration),
effectDuration:
effectDuration !== null
? formatDurationToMicrosecondsGranularity(effectDuration)
: null,
fiberActualDurations,
fiberSelfDurations,
passiveEffectDuration,
passiveEffectDuration:
passiveEffectDuration !== null
? formatDurationToMicrosecondsGranularity(passiveEffectDuration)
: null,
Copy link
Contributor

Choose a reason for hiding this comment

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

Would it be cleaner to have formatDurationToMicrosecondsGranularity take null? (I don't have a preference)

Comment on lines +334 to +342

// 0.123456789 => 0.123
// Expects high-resolution timestamp in milliseconds, like from performance.now()
// Mainly used for optimizing the size of serialized profiling payload
export function formatDurationToMicrosecondsGranularity(
duration: number,
): number {
return Math.round(duration * 1000) / 1000;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Would there be a risk of the frontend precision being out of sync with this here? I'd imagine an all-in solution involving the frontend declaring a precision somehow. (not saying we need it in this PR tho)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Technically, yes, if we decide to start showing durations with increased granularity. This is not the case for browser extension, though, because backend and frontend are shipped in a single version lockstep.

@EdmondChuiHW
Copy link
Contributor

EdmondChuiHW commented Oct 8, 2024

Also, do we have a rough estimate of how much bandwidth this would save/visible speed improvement? Very intrigued as I never thought of using number precision as an optimisation. Big if true!

@hoxyq
Copy link
Contributor Author

hoxyq commented Oct 9, 2024

Also, do we have a rough estimate of how much bandwidth this would save/visible speed improvement? Very intrigued as I never thought of using number precision as an optimisation. Big if true!

React DevTools profiling payload has data for each commit. Every commit will have 2 collections: [FiberID, FiberActualDuration] and [FiberID, FiberSelfDuration]. Depending on how big the app is, and how many Fibers were involved in a specific commit, these collections can get really big, like multiple thousands of elements.

In this PR we are mainly optimizing both FiberActualDuration and FiberSelfDuration, as well as other durations, but they don't have that big of effect. From my estimations, this reduces the serialized profiling payload size by ~35%.

It is safe to do it, since we don't actually use it from the Frontend side, see the description.

@hoxyq hoxyq merged commit 389a2de into facebook:main Oct 9, 2024
184 checks passed
@hoxyq hoxyq deleted the react-devtools/optimize-durations-for-serialization branch October 9, 2024 12:26
hoxyq added a commit that referenced this pull request Oct 9, 2024
Stacked on #31118. See last
commit.

We don't need to call `startProfiling()` here, because we delegate this
to the Renderer itself:

https://github.com/facebook/react/blob/830e823cd2c6ee675636d31320b10350e8ade9ae/packages/react-devtools-shared/src/backend/fiber/renderer.js#L5227-L5232

Since this is de-facto the constructor of Renderer, this will be called
earlier.

Validated via testing the reload-to-profile for Chrome browser
extension.
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.

3 participants