Skip to content

PerformanceObserver: default durationThreshold to 104ms#56506

Closed
rubennorte wants to merge 1 commit intofacebook:mainfrom
rubennorte:export-D101629586
Closed

PerformanceObserver: default durationThreshold to 104ms#56506
rubennorte wants to merge 1 commit intofacebook:mainfrom
rubennorte:export-D101629586

Conversation

@rubennorte
Copy link
Copy Markdown
Contributor

Summary:
React Native's PerformanceObserver previously defaulted durationThreshold to 0 for event entries, while the W3C Event Timing spec
(https://www.w3.org/TR/event-timing/#sec-modifications-perf-timeline) mandates a default of 104ms. The previous default flooded observers with short events
(clicks, pointer up/down) that are not interesting for responsiveness
measurement.

This change brings React Native in line with the spec by making 104ms the
default. The default is applied at the JSI bridge boundary in
NativePerformance.cpp (the JS API boundary on the C++ side) when JS does not
provide an explicit durationThreshold. The C++ public observer API
(PerformanceObserverObserveSingleOptions::durationThreshold) and the global
event buffer (eventBuffer_.durationThreshold) keep their HighResDuration::zero()
default — applying 104ms to the global buffer would drop sub-104ms events at
the source, breaking observers that explicitly request durationThreshold: 0.

Changes in react-native:

  • NativePerformance.cpp: apply 104ms default at the JSI bridge boundary.
  • PerformanceApiExample.js (rn-tester): pass durationThreshold: 0 to
    preserve previous behavior.
  • EventTimingAPI-itest.js: migrate 4 existing call sites to
    {type: 'event', durationThreshold: 0} and add a new test verifying the
    104ms default.

Sites using {entryTypes: ['event']} were converted to
{type: 'event', durationThreshold: 0} since the spec (and existing JS
validation in PerformanceObserver.js) disallows durationThreshold together
with entryTypes.

Changelog: [General][Fixed] - PerformanceObserver: observe({type: 'event'}) now correctly defaults durationThreshold to 104ms per the W3C Event Timing spec instead of reporting all events.

Differential Revision: D101629586

Summary:
React Native's `PerformanceObserver` previously defaulted `durationThreshold` to 0 for `event` entries, while the W3C Event Timing spec
(https://www.w3.org/TR/event-timing/#sec-modifications-perf-timeline) mandates a default of 104ms. The previous default flooded observers with short events
(clicks, pointer up/down) that are not interesting for responsiveness
measurement.

This change brings React Native in line with the spec by making 104ms the
default. The default is applied at the JSI bridge boundary in
`NativePerformance.cpp` (the JS API boundary on the C++ side) when JS does not
provide an explicit `durationThreshold`. The C++ public observer API
(`PerformanceObserverObserveSingleOptions::durationThreshold`) and the global
event buffer (`eventBuffer_.durationThreshold`) keep their `HighResDuration::zero()`
default — applying 104ms to the global buffer would drop sub-104ms events at
the source, breaking observers that explicitly request `durationThreshold: 0`.

Changes in `react-native`:
- `NativePerformance.cpp`: apply 104ms default at the JSI bridge boundary.
- `PerformanceApiExample.js` (rn-tester): pass `durationThreshold: 0` to
  preserve previous behavior.
- `EventTimingAPI-itest.js`: migrate 4 existing call sites to
  `{type: 'event', durationThreshold: 0}` and add a new test verifying the
  104ms default.

Sites using `{entryTypes: ['event']}` were converted to
`{type: 'event', durationThreshold: 0}` since the spec (and existing JS
validation in `PerformanceObserver.js`) disallows `durationThreshold` together
with `entryTypes`.

Changelog: [General][Fixed] - PerformanceObserver: `observe({type: 'event'})` now correctly defaults `durationThreshold` to 104ms per the W3C Event Timing spec instead of reporting all events.

Differential Revision: D101629586
@meta-cla meta-cla bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Apr 20, 2026
@meta-codesync
Copy link
Copy Markdown

meta-codesync bot commented Apr 20, 2026

@rubennorte has exported this pull request. If you are a Meta employee, you can view the originating Diff in D101629586.

@react-native-bot
Copy link
Copy Markdown
Collaborator

This pull request was successfully merged by @rubennorte in 65c561e

When will my fix make it into a release? | How to file a pick request?

@react-native-bot react-native-bot added the Merged This PR has been merged. label Apr 20, 2026
@meta-codesync
Copy link
Copy Markdown

meta-codesync bot commented Apr 20, 2026

This pull request has been merged in 65c561e.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. fb-exported Merged This PR has been merged. meta-exported p: Facebook Partner: Facebook Partner

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants