Switch trace event chunks from event count to size based#56080
Closed
huntie wants to merge 2 commits intofacebook:mainfrom
Closed
Switch trace event chunks from event count to size based#56080huntie wants to merge 2 commits intofacebook:mainfrom
huntie wants to merge 2 commits intofacebook:mainfrom
Conversation
Summary: Update Android frame screenshot processing to skip screenshot capture when encoding is already in progress — now limited to a single background thread — while always emitting frame timing events. **Motivation** 1. Prevents truncated trace data on slower devices (e.g. missing screenshots for the last 1/3 of the trace), with the tradeoff of some intermediate frame screenshot loss. 2. Reduces total recording overhead by freeing up device threads - prevents excessive encoding work from blocking or slowing down the UI and other app threads. **Algorithm** Uses `encodingInProgress` atomic flag with single encoding thread and `lastFrameBuffer` storage for tail-capture of the last frame before idling (to capture settled animation states): - **Not encoding:** Frame passes directly to encoder → emits with screenshot when done - **Encoding busy:** Frame stored in `lastFrameBuffer` for tail-capture → any replaced frame emits without screenshot - **Encoding done:** Clears flag early, then opportunistically encodes tail frame without blocking new frames - **Failed captures:** Emit without screenshot immediately Result: Every frame emitted exactly once. Encoding adapts to device speed. Settled animation state guaranteed captured. **Remaining work** -⚠️ This still does not yet solve crashes (OkHttp network chunk size overflow) for heavy frame data at a high FPS on fast devices (coming next). Changelog: [Internal] Reviewed By: rubennorte Differential Revision: D95987488
Summary: Trace event chunks were previously split by a fixed event count (1000). This caused issues with Frame Timing events containing screenshot data, where a single chunk could produce CDP messages of tens or hundreds of MBs — exceeding the OkHttp WebSocket limit (app crash). Address this problem by replacing count-based chunking with size-based chunking (max 10 MiB per chunk) for `emitFrameTimings()` and `emitPerformanceTraceEvents()`. A new `TraceEventSerializer::estimateJsonSize()` utility recursively estimates the serialized byte size of a `folly::dynamic` value to avoid double-serialization overhead. **Notes** - RuntimeSamplingProfile chunks (separate code path) remain count-based (inherently small, no screenshot data). Changelog: [Internal] Reviewed By: rubennorte Differential Revision: D96206962
|
This pull request has been merged in d3b33f5. |
huntie
added a commit
to huntie/react-native
that referenced
this pull request
Mar 31, 2026
) Summary: Pull Request resolved: facebook#56080 Trace event chunks were previously split by a fixed event count (1000). This caused issues with Frame Timing events containing screenshot data, where a single chunk could produce CDP messages of tens or hundreds of MBs — exceeding the OkHttp WebSocket limit (app crash). Address this problem by replacing count-based chunking with size-based chunking (max 10 MiB per chunk) for `emitFrameTimings()` and `emitPerformanceTraceEvents()`. A new `TraceEventSerializer::estimateJsonSize()` utility recursively estimates the serialized byte size of a `folly::dynamic` value to avoid double-serialization overhead. **Notes** - RuntimeSamplingProfile chunks (separate code path) remain count-based (inherently small, no screenshot data). Changelog: [Internal] Reviewed By: rubennorte Differential Revision: D96206962 fbshipit-source-id: 6b6e4db76441f174c46bf34905292585d0e30899
huntie
pushed a commit
to huntie/react-native
that referenced
this pull request
Apr 8, 2026
Backports some CDP Performance features and stability improvements to `0.83-stable`. This includes: - Remaining implementation of Frame Timings and screenshot capture in performance traces (Android) - New support for Frame Timings and screenshot capture on iOS - Optimisations to trace chunk generation, memory usage during performance recording - `Page.captureScreenshot` (Android, iOS) All features remain gated behind feature flags (`fuseboxFrameRecordingEnabled`, `fuseboxScreenshotCaptureEnabled`). **Commits applied** - Define TracingCategory enum (facebook#54377) bd6c6bf - Use TracingCategory in TraceEvent (facebook#54378) ce60f27 - Simple parser for serialized tracing categories (facebook#54379) 62275b6 - Propagate tracing categories to recording state (facebook#54380) 3841ef0 - Re-land "Revert D85999774: [rn][android] Add FrameTiming module" (facebook#54502) 85905ad - Add screenshot category (facebook#54537) 5d9cb80 - Define HostTargetTracingDelegate (facebook#54622) be0dae0 - Define TracingDelegate for Android Host (facebook#54628) a212e95 - Use new API for tracing state on Android (facebook#54629) 532d0be - Internalize TracingState interface (facebook#54631) 58ec261 - Move TracingState interfaces to inspector package (facebook#54632) 10d0d99 - Rename values of TracingState enum (facebook#54630) be94707 - FrameTiming module to subscribe to Inspector tracing lifecycle (facebook#54633) 04ee02b - Clarify HostTracingProfile and HostTraceRecordingState (facebook#54677) ec92f12 - Introduce TimeWindowedBuffer (facebook#54679) d6ee54f - Keep tracing time window on TraceRecordingState (facebook#54673) e651563 - Define FrameTimingSequence (facebook#54674) 5b7d92f - Define an endpoint on HostTarget to capture frame timings (facebook#54672) f469aa3 - Extract frame trace events construction logic (facebook#54675) 57973fa - Define serializers for frame timings as part of HostTargetTracingProfile (facebook#54681) 587d360 - Propagate Frames data through Host (facebook#54671) 26ff069 - Cleanup no longer used jni layer for frame timings (facebook#54678) 9ba4ce6 - Fix screenshot typo (facebook#54742) 52186a3 - Add optional screenshot argument to FrameTimingSequence (facebook#54743) 57c29fc - Frame screenshot event generation (facebook#54744) b447d26 - Frame screenshots capture implementation (facebook#54745) f3c9a8d - BeginDrawing: INTENDED_VSYNC_TIMESTAMP -> VSYNC_TIMESTAMP (facebook#54765) 9221772 - Add frames category (facebook#54768) 31a0c9a - Specify correct category for SetLayerTreeId event (facebook#54769) cd055e9 - Reduce the screenshots size (facebook#54800) e4a5a56 - Remove Commit from FrameTimingSequence (facebook#54779) 39f7703 - Fix potential bitmap leaks in FrameTimingsObserver (facebook#55652) 3918dd1 - Capture initial screenshot when starting frame timing trace (facebook#55720) 863f5c0 - Refactor FrameTimingsObserver for multi-activity support (facebook#55740) 8230f3b - Reorder FrameTimingsObserver methods (facebook#55743) f56b295 - Increase frame capture quality, apply scaling after DPI normalization (facebook#55731) e5f9f5f - Fix FrameTimingsObverver to initiate PixelCopy on main thread (facebook#55744) d552f2a - Fix bitmap reuse race condition in FrameTimingsObserver (facebook#55745) 3924768 - Fix trailing frame capture after recording ended (facebook#55704) 47684ca - Move base64Encode into react/utils (facebook#55873) 422770d - Move screenshot Base64 encoding to trace serialization (facebook#55803) dc4c36e - Restore inspector addPage listener callback (facebook#55925) 8c763fc - Add tracing helper functions for RNDT traces in C++ and Kotlin (facebook#55935) 4f3f536 - Introduce fuseboxFrameRecordingEnabled flag, gate existing code (facebook#55941) 1aa7a32 - Implement Performance frames and screenshots on iOS (facebook#56015) 64a1a10 - Add pixel diffing to RCTFrameTimingsObserver (facebook#56043) 9d231af - Add dynamic sampling to frame screenshots (facebook#56048) d309cda - Switch trace event chunks from event count to size based (facebook#56080) d3b33f5 - Increase trace screenshot scale factor to 1x (facebook#56079) 972a30d - Add Page.captureScreenshot CDP support (facebook#56307) 77332d2 - Fix data race on PerformanceObserver entry buffer (facebook#56352) 5eb1ca1 - [LOCAL] Remove stale frame event code from PerformanceTracer - [LOCAL] Update Podfile.lock
huntie
pushed a commit
to huntie/react-native
that referenced
this pull request
Apr 8, 2026
Backports some CDP Performance features and stability improvements to `0.83-stable`. This includes: - Remaining implementation of Frame Timings and screenshot capture in performance traces (Android) - New support for Frame Timings and screenshot capture on iOS - Optimisations to trace chunk generation, memory usage during performance recording - `Page.captureScreenshot` (Android, iOS) All features remain gated behind feature flags (`fuseboxFrameRecordingEnabled`, `fuseboxScreenshotCaptureEnabled`). **Commits applied** - Define TracingCategory enum (facebook#54377) bd6c6bf - Use TracingCategory in TraceEvent (facebook#54378) ce60f27 - Simple parser for serialized tracing categories (facebook#54379) 62275b6 - Propagate tracing categories to recording state (facebook#54380) 3841ef0 - Re-land "Revert D85999774: [rn][android] Add FrameTiming module" (facebook#54502) 85905ad - Add screenshot category (facebook#54537) 5d9cb80 - Define HostTargetTracingDelegate (facebook#54622) be0dae0 - Define TracingDelegate for Android Host (facebook#54628) a212e95 - Use new API for tracing state on Android (facebook#54629) 532d0be - Internalize TracingState interface (facebook#54631) 58ec261 - Move TracingState interfaces to inspector package (facebook#54632) 10d0d99 - Rename values of TracingState enum (facebook#54630) be94707 - FrameTiming module to subscribe to Inspector tracing lifecycle (facebook#54633) 04ee02b - Clarify HostTracingProfile and HostTraceRecordingState (facebook#54677) ec92f12 - Introduce TimeWindowedBuffer (facebook#54679) d6ee54f - Keep tracing time window on TraceRecordingState (facebook#54673) e651563 - Define FrameTimingSequence (facebook#54674) 5b7d92f - Define an endpoint on HostTarget to capture frame timings (facebook#54672) f469aa3 - Extract frame trace events construction logic (facebook#54675) 57973fa - Define serializers for frame timings as part of HostTargetTracingProfile (facebook#54681) 587d360 - Propagate Frames data through Host (facebook#54671) 26ff069 - Cleanup no longer used jni layer for frame timings (facebook#54678) 9ba4ce6 - Fix screenshot typo (facebook#54742) 52186a3 - Add optional screenshot argument to FrameTimingSequence (facebook#54743) 57c29fc - Frame screenshot event generation (facebook#54744) b447d26 - Frame screenshots capture implementation (facebook#54745) f3c9a8d - BeginDrawing: INTENDED_VSYNC_TIMESTAMP -> VSYNC_TIMESTAMP (facebook#54765) 9221772 - Add frames category (facebook#54768) 31a0c9a - Specify correct category for SetLayerTreeId event (facebook#54769) cd055e9 - Reduce the screenshots size (facebook#54800) e4a5a56 - Remove Commit from FrameTimingSequence (facebook#54779) 39f7703 - Fix potential bitmap leaks in FrameTimingsObserver (facebook#55652) 3918dd1 - Capture initial screenshot when starting frame timing trace (facebook#55720) 863f5c0 - Refactor FrameTimingsObserver for multi-activity support (facebook#55740) 8230f3b - Reorder FrameTimingsObserver methods (facebook#55743) f56b295 - Increase frame capture quality, apply scaling after DPI normalization (facebook#55731) e5f9f5f - Fix FrameTimingsObverver to initiate PixelCopy on main thread (facebook#55744) d552f2a - Fix bitmap reuse race condition in FrameTimingsObserver (facebook#55745) 3924768 - Fix trailing frame capture after recording ended (facebook#55704) 47684ca - Move base64Encode into react/utils (facebook#55873) 422770d - Move screenshot Base64 encoding to trace serialization (facebook#55803) dc4c36e - Restore inspector addPage listener callback (facebook#55925) 8c763fc - Add tracing helper functions for RNDT traces in C++ and Kotlin (facebook#55935) 4f3f536 - Introduce fuseboxFrameRecordingEnabled flag, gate existing code (facebook#55941) 1aa7a32 - Implement Performance frames and screenshots on iOS (facebook#56015) 64a1a10 - Add pixel diffing to RCTFrameTimingsObserver (facebook#56043) 9d231af - Add dynamic sampling to frame screenshots (facebook#56048) d309cda - Switch trace event chunks from event count to size based (facebook#56080) d3b33f5 - Increase trace screenshot scale factor to 1x (facebook#56079) 972a30d - Add Page.captureScreenshot CDP support (facebook#56307) 77332d2 - Fix data race on PerformanceObserver entry buffer (facebook#56352) 5eb1ca1 - [LOCAL] Remove stale frame event code from PerformanceTracer - [LOCAL] Update Podfile.lock
huntie
added a commit
to huntie/react-native
that referenced
this pull request
Apr 9, 2026
Backports some CDP Performance features and stability improvements to `0.83-stable`. This includes: - Remaining implementation of Frame Timings and screenshot capture in performance traces (Android) - New support for Frame Timings and screenshot capture on iOS - Optimisations to trace chunk generation, memory usage during performance recording - `Page.captureScreenshot` (Android, iOS) All features remain gated behind feature flags (`fuseboxFrameRecordingEnabled`, `fuseboxScreenshotCaptureEnabled`). **Commits applied** - Define TracingCategory enum (facebook#54377) bd6c6bf - Use TracingCategory in TraceEvent (facebook#54378) ce60f27 - Simple parser for serialized tracing categories (facebook#54379) 62275b6 - Propagate tracing categories to recording state (facebook#54380) 3841ef0 - Re-land "Revert D85999774: [rn][android] Add FrameTiming module" (facebook#54502) 85905ad - Add screenshot category (facebook#54537) 5d9cb80 - Define HostTargetTracingDelegate (facebook#54622) be0dae0 - Define TracingDelegate for Android Host (facebook#54628) a212e95 - Use new API for tracing state on Android (facebook#54629) 532d0be - Internalize TracingState interface (facebook#54631) 58ec261 - Move TracingState interfaces to inspector package (facebook#54632) 10d0d99 - Rename values of TracingState enum (facebook#54630) be94707 - FrameTiming module to subscribe to Inspector tracing lifecycle (facebook#54633) 04ee02b - Clarify HostTracingProfile and HostTraceRecordingState (facebook#54677) ec92f12 - Introduce TimeWindowedBuffer (facebook#54679) d6ee54f - Keep tracing time window on TraceRecordingState (facebook#54673) e651563 - Define FrameTimingSequence (facebook#54674) 5b7d92f - Define an endpoint on HostTarget to capture frame timings (facebook#54672) f469aa3 - Extract frame trace events construction logic (facebook#54675) 57973fa - Define serializers for frame timings as part of HostTargetTracingProfile (facebook#54681) 587d360 - Propagate Frames data through Host (facebook#54671) 26ff069 - Cleanup no longer used jni layer for frame timings (facebook#54678) 9ba4ce6 - Fix screenshot typo (facebook#54742) 52186a3 - Add optional screenshot argument to FrameTimingSequence (facebook#54743) 57c29fc - Frame screenshot event generation (facebook#54744) b447d26 - Frame screenshots capture implementation (facebook#54745) f3c9a8d - BeginDrawing: INTENDED_VSYNC_TIMESTAMP -> VSYNC_TIMESTAMP (facebook#54765) 9221772 - Add frames category (facebook#54768) 31a0c9a - Specify correct category for SetLayerTreeId event (facebook#54769) cd055e9 - Reduce the screenshots size (facebook#54800) e4a5a56 - Remove Commit from FrameTimingSequence (facebook#54779) 39f7703 - Fix potential bitmap leaks in FrameTimingsObserver (facebook#55652) 3918dd1 - Capture initial screenshot when starting frame timing trace (facebook#55720) 863f5c0 - Refactor FrameTimingsObserver for multi-activity support (facebook#55740) 8230f3b - Reorder FrameTimingsObserver methods (facebook#55743) f56b295 - Increase frame capture quality, apply scaling after DPI normalization (facebook#55731) e5f9f5f - Fix FrameTimingsObverver to initiate PixelCopy on main thread (facebook#55744) d552f2a - Fix bitmap reuse race condition in FrameTimingsObserver (facebook#55745) 3924768 - Fix trailing frame capture after recording ended (facebook#55704) 47684ca - Move base64Encode into react/utils (facebook#55873) 422770d - Move screenshot Base64 encoding to trace serialization (facebook#55803) dc4c36e - Restore inspector addPage listener callback (facebook#55925) 8c763fc - Add tracing helper functions for RNDT traces in C++ and Kotlin (facebook#55935) 4f3f536 - Introduce fuseboxFrameRecordingEnabled flag, gate existing code (facebook#55941) 1aa7a32 - Implement Performance frames and screenshots on iOS (facebook#56015) 64a1a10 - Add pixel diffing to RCTFrameTimingsObserver (facebook#56043) 9d231af - Add dynamic sampling to frame screenshots (facebook#56048) d309cda - Switch trace event chunks from event count to size based (facebook#56080) d3b33f5 - Increase trace screenshot scale factor to 1x (facebook#56079) 972a30d - Add Page.captureScreenshot CDP support (facebook#56307) 77332d2 - Fix data race on PerformanceObserver entry buffer (facebook#56352) 5eb1ca1 - Add dynamic sampling to frame screenshots (facebook#56135) e0d1e29 - Increase trace screenshot scale factor to 1x (facebook#56136) 90e02fa - Add missing debugger define for React-RuntimeApple (facebook#56397) - [LOCAL] Remove stale frame event code from PerformanceTracer - [LOCAL] Update Podfile.lock
gabrieldonadel
pushed a commit
that referenced
this pull request
Apr 13, 2026
Backports some CDP Performance features and stability improvements to `0.83-stable`. This includes: - Remaining implementation of Frame Timings and screenshot capture in performance traces (Android) - New support for Frame Timings and screenshot capture on iOS - Optimisations to trace chunk generation, memory usage during performance recording - `Page.captureScreenshot` (Android, iOS) All features remain gated behind feature flags (`fuseboxFrameRecordingEnabled`, `fuseboxScreenshotCaptureEnabled`). **Commits applied** - Define TracingCategory enum (#54377) bd6c6bf - Use TracingCategory in TraceEvent (#54378) ce60f27 - Simple parser for serialized tracing categories (#54379) 62275b6 - Propagate tracing categories to recording state (#54380) 3841ef0 - Re-land "Revert D85999774: [rn][android] Add FrameTiming module" (#54502) 85905ad - Add screenshot category (#54537) 5d9cb80 - Define HostTargetTracingDelegate (#54622) be0dae0 - Define TracingDelegate for Android Host (#54628) a212e95 - Use new API for tracing state on Android (#54629) 532d0be - Internalize TracingState interface (#54631) 58ec261 - Move TracingState interfaces to inspector package (#54632) 10d0d99 - Rename values of TracingState enum (#54630) be94707 - FrameTiming module to subscribe to Inspector tracing lifecycle (#54633) 04ee02b - Clarify HostTracingProfile and HostTraceRecordingState (#54677) ec92f12 - Introduce TimeWindowedBuffer (#54679) d6ee54f - Keep tracing time window on TraceRecordingState (#54673) e651563 - Define FrameTimingSequence (#54674) 5b7d92f - Define an endpoint on HostTarget to capture frame timings (#54672) f469aa3 - Extract frame trace events construction logic (#54675) 57973fa - Define serializers for frame timings as part of HostTargetTracingProfile (#54681) 587d360 - Propagate Frames data through Host (#54671) 26ff069 - Cleanup no longer used jni layer for frame timings (#54678) 9ba4ce6 - Fix screenshot typo (#54742) 52186a3 - Add optional screenshot argument to FrameTimingSequence (#54743) 57c29fc - Frame screenshot event generation (#54744) b447d26 - Frame screenshots capture implementation (#54745) f3c9a8d - BeginDrawing: INTENDED_VSYNC_TIMESTAMP -> VSYNC_TIMESTAMP (#54765) 9221772 - Add frames category (#54768) 31a0c9a - Specify correct category for SetLayerTreeId event (#54769) cd055e9 - Reduce the screenshots size (#54800) e4a5a56 - Remove Commit from FrameTimingSequence (#54779) 39f7703 - Fix potential bitmap leaks in FrameTimingsObserver (#55652) 3918dd1 - Capture initial screenshot when starting frame timing trace (#55720) 863f5c0 - Refactor FrameTimingsObserver for multi-activity support (#55740) 8230f3b - Reorder FrameTimingsObserver methods (#55743) f56b295 - Increase frame capture quality, apply scaling after DPI normalization (#55731) e5f9f5f - Fix FrameTimingsObverver to initiate PixelCopy on main thread (#55744) d552f2a - Fix bitmap reuse race condition in FrameTimingsObserver (#55745) 3924768 - Fix trailing frame capture after recording ended (#55704) 47684ca - Move base64Encode into react/utils (#55873) 422770d - Move screenshot Base64 encoding to trace serialization (#55803) dc4c36e - Restore inspector addPage listener callback (#55925) 8c763fc - Add tracing helper functions for RNDT traces in C++ and Kotlin (#55935) 4f3f536 - Introduce fuseboxFrameRecordingEnabled flag, gate existing code (#55941) 1aa7a32 - Implement Performance frames and screenshots on iOS (#56015) 64a1a10 - Add pixel diffing to RCTFrameTimingsObserver (#56043) 9d231af - Add dynamic sampling to frame screenshots (#56048) d309cda - Switch trace event chunks from event count to size based (#56080) d3b33f5 - Increase trace screenshot scale factor to 1x (#56079) 972a30d - Add Page.captureScreenshot CDP support (#56307) 77332d2 - Fix data race on PerformanceObserver entry buffer (#56352) 5eb1ca1 - Add dynamic sampling to frame screenshots (#56135) e0d1e29 - Increase trace screenshot scale factor to 1x (#56136) 90e02fa - Add missing debugger define for React-RuntimeApple (#56397) - [LOCAL] Remove stale frame event code from PerformanceTracer - [LOCAL] Update Podfile.lock
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary:
Trace event chunks were previously split by a fixed event count (1000). This caused issues with Frame Timing events containing screenshot data, where a single chunk could produce CDP messages of tens or hundreds of MBs — exceeding the OkHttp WebSocket limit (app crash).
Address this problem by replacing count-based chunking with size-based chunking (max 10 MiB per chunk) for
emitFrameTimings()andemitPerformanceTraceEvents(). A newTraceEventSerializer::estimateJsonSize()utility recursively estimates the serialized byte size of afolly::dynamicvalue to avoid double-serialization overhead.Notes
Changelog: [Internal]
Reviewed By: rubennorte
Differential Revision: D96206962