Skip to content

Add idle frame support to Performance timeline - #57952

Open
huntie wants to merge 1 commit into
react:mainfrom
huntie:export-D97502569
Open

Add idle frame support to Performance timeline#57952
huntie wants to merge 1 commit into
react:mainfrom
huntie:export-D97502569

Conversation

@huntie

@huntie huntie commented Aug 13, 2026

Copy link
Copy Markdown
Member

Summary:
Implement Idle frame spans in React Native DevTools, by emitting synthetic NeedsBeginFrameChanged + BeginFrame events.

Definition

An idle frame is emitted whenever the gap between two consecutive frames exceeds one vsync interval, derived from the display's refresh rate (CADisplayLink.duration on iOS, Display.refreshRate on Android, falling back to 60 Hz).

   frame N                  gap > 1 vsync                 frame N+1
+------------+  +--------------------------------+  +------------+
| BeginFrame |  | NeedsBeginFrameChanged         |  | BeginFrame |
| DrawFrame  |  | BeginFrame     (no DrawFrame)  |  | DrawFrame  |
+------------+  +--------------------------------+  +------------+
                    rendered as an "Idle frame"

Implementation notes

  • Drop frames that begin before the recording start — Android FrameMetrics can deliver frames from app startup, and the first iOS CADisplayLink callback reports the previous vsync.
  • Sort frames by begin timestamp before serializing, since async screenshot encoding can deliver them out of order and break gap detection.
  • iOS: skip the frame event when the screenshot is unchanged, letting the gap render as an idle frame.

Changelog: [Internal]

Differential Revision: D97502569

Summary:
Implement Idle frame spans in Chrome DevTools, by emitting synthetic `NeedsBeginFrameChanged` + `BeginFrame` events.

**Definition**

An idle frame is emitted whenever the gap between two consecutive frames exceeds one vsync interval, derived from the display's refresh rate (`CADisplayLink.duration` on iOS, `Display.refreshRate` on Android, falling back to 60 Hz).

```
   frame N                  gap > 1 vsync                 frame N+1
+------------+  +--------------------------------+  +------------+
| BeginFrame |  | NeedsBeginFrameChanged         |  | BeginFrame |
| DrawFrame  |  | BeginFrame     (no DrawFrame)  |  | DrawFrame  |
+------------+  +--------------------------------+  +------------+
                    rendered as an "Idle frame"
```

**Implementation notes**

- Drop frames that begin before the recording start — Android `FrameMetrics` can deliver frames from app startup, and the first iOS `CADisplayLink` callback reports the previous vsync.
- Sort frames by begin timestamp before serializing, since async screenshot encoding can deliver them out of order and break gap detection.
- iOS: skip the frame event when the screenshot is unchanged, letting the gap render as an idle frame.

Changelog: [Internal]

Differential Revision: D97502569
@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 Aug 13, 2026
@meta-codesync

meta-codesync Bot commented Aug 13, 2026

Copy link
Copy Markdown

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

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. meta-exported p: Facebook Partner: Facebook Partner

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant