Skip to content

Conversation

sbarrio
Copy link
Contributor

@sbarrio sbarrio commented Oct 16, 2025

What does this PR do?

This PR adds a normalization step to the tracking of the js refresh rate metric, making it so that all reported values fall within the 0-60hz bracket.

I've added a convenience function that will handle normalization as well as obtaining the device capabilities and then normalize the input frame time accordingly.

This is a breaking change, as once users update to V3 all their js refresh rates will get normalized.

NOTE: The metric provider for the RN SDK works with frame times in seconds and they are reported as such to the backend, where they are turned into FPS metrics, that's the reason why the normalization function works with frame times and not fps values.

Motivation

As we state on our Mobile Vitals documentation:

"Refresh rates are normalized on a range of zero to 60fps. For example, if your application runs at 100fps on a device capable of rendering 120fps, Datadog reports 50fps in Mobile Vitals."

This, however, was not correct for js refresh rates, which we being reported without normalization, so devices capable of higher refresh rates than 60hz could report values above that bracket. This was confusing and not consistent with the expectations laid out by the documentation, so we needed to fix it.

Review checklist (to be filled by reviewers)

  • Feature or bugfix MUST have appropriate tests
  • Make sure you discussed the feature or bugfix with the maintaining team in an Issue
  • Make sure each commit and the PR mention the Issue number (cf the CONTRIBUTING doc)
  • If this PR is auto-generated, please make sure also to manually update the code related to the change

@sbarrio sbarrio changed the title [React Native] [V3] JS Refresh Rate nornalization [RUM-11606] [V3] JS Refresh Rate nornalization Oct 16, 2025
@sbarrio sbarrio changed the base branch from develop to feature/v3 October 16, 2025 09:20
@sbarrio sbarrio force-pushed the sbarrio/RUM-11606/js-refresh-rate-normalization branch 2 times, most recently from 8384763 to 6fd6016 Compare October 16, 2025 09:41
@sbarrio sbarrio changed the title [RUM-11606] [V3] JS Refresh Rate nornalization [RUM-11606] [V3] JS Refresh Rate normalization to (0-60fps) Oct 16, 2025
@sbarrio sbarrio changed the title [RUM-11606] [V3] JS Refresh Rate normalization to (0-60fps) [RUM-11606] [V3] JS Refresh Rate normalization to 0-60 fps Oct 16, 2025
@sbarrio sbarrio self-assigned this Oct 16, 2025
@sbarrio sbarrio marked this pull request as ready for review October 16, 2025 10:35
@sbarrio sbarrio requested a review from a team as a code owner October 16, 2025 10:35
Copy link
Member

@marco-saia-datadog marco-saia-datadog left a comment

Choose a reason for hiding this comment

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

Great work 🚀

Two questions:

  • Is this aligned 1:1 with the native SDKs logic?
  • Have you manually tested this?

* @param fpsBudget: The maximum fps under which the frame Time will be normalized [0-fpsBudget]. Defaults to 60Hz.
* @param deviceDisplayFps: The maximum fps supported by the device. If not provided it will be set from the value obtained from the app context.
*/
@Suppress("ComplexMethod")
Copy link
Member

Choose a reason for hiding this comment

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

Quick heads-up: once we rebase develop on feature/v3, because of a bump in the detekt plugin version needed for RN 0.82 and Gradle 9 support, this will have to be changed to CyclomaticComplexMethod, or it won't be picked up and checks will fail.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for raising!

I've already changed it here: 6e58ddf

@sbarrio
Copy link
Contributor Author

sbarrio commented Oct 20, 2025

Great work 🚀

Two questions:

  • Is this aligned 1:1 with the native SDKs logic?

Yes, this logic follows the one performed on the native side. The only main difference is that native SDKs report fps metrics instead of frame times. I've decided to keep frame time on the RN SDK as that's the metric that was already defined and exposed by the native SDK for the RN side to report to the backend:

iOS: https://github.com/DataDog/dd-sdk-ios/blob/9fbc8f68e9ce010ca40107b54af1e297eaef3062/DatadogRUM/Sources/RUMVitals/PerformanceMetric.swift#L16-L18

Android: https://github.com/DataDog/dd-sdk-android/blob/ad12432ed6b0d9c11aae3eb4b01c0dfbb128c01c/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/RumPerformanceMetric.kt#L19-L21

  • Have you manually tested this?

Yes, I have tested it manually on iOS and Android devices, Both running on old and new architecture.

@sbarrio sbarrio force-pushed the sbarrio/RUM-11606/js-refresh-rate-normalization branch from 6fd6016 to 6e58ddf Compare October 20, 2025 13:05
@marco-saia-datadog marco-saia-datadog self-requested a review October 20, 2025 13:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants