From 948abb7a934f00c74045066717357bfd923a48ed Mon Sep 17 00:00:00 2001 From: Ruslan Lesiutin Date: Fri, 19 Sep 2025 04:27:04 -0700 Subject: [PATCH 1/2] Manually preserve ordering for Scheduler and Components tracks (#53853) Summary: # Changelog: [Internal] Chrome DevTools orders tracks based on the timestamp of the first entry. For React on Web we emit a few entries to establish the ordering: https://github.com/facebook/react/blob/6eda534718d09a26d58d65c0a376e05d7e2a3358/packages/react-reconciler/src/ReactFiberPerformanceTrack.js#L57-L96 We are doing the same thing here, but in C++. Differential Revision: D82811889 --- .../tracing/PerformanceTracer.cpp | 29 +++++++++++++++++++ .../tracing/PerformanceTracer.h | 4 +++ 2 files changed, 33 insertions(+) diff --git a/packages/react-native/ReactCommon/jsinspector-modern/tracing/PerformanceTracer.cpp b/packages/react-native/ReactCommon/jsinspector-modern/tracing/PerformanceTracer.cpp index 7ea2a93df276..3d2f0e80d9eb 100644 --- a/packages/react-native/ReactCommon/jsinspector-modern/tracing/PerformanceTracer.cpp +++ b/packages/react-native/ReactCommon/jsinspector-modern/tracing/PerformanceTracer.cpp @@ -90,6 +90,7 @@ std::optional> PerformanceTracer::stopTracing() { tracingAtomic_ = false; performanceMeasureCount_ = 0; + alreadyEmittedEntryForComponentsTrackOrdering_ = false; events = collectEventsAndClearBuffers(currentTraceEndTime); } @@ -571,6 +572,34 @@ void PerformanceTracer::enqueueTraceEventsFromPerformanceTracerEvent( data["end"] = std::move(std::get(*event.end)); } } + + // We add a custom synthetic entry here to manually put Components + // track right under the Scheduler track. Will be removed once CDT + // Frontend preserves track ordering and we upgrade the fork. + if (!alreadyEmittedEntryForComponentsTrackOrdering_ && + event.trackName && !event.trackGroup) { + if (*event.trackName == "Components \u269B") { + alreadyEmittedEntryForComponentsTrackOrdering_ = true; + // React is using 0.003 for Scheduler sub-tracks. + auto timestamp = highResTimeStampToTracingClockTimeStamp( + HighResTimeStamp::fromDOMHighResTimeStamp(0.004)); + events.emplace_back(TraceEvent{ + .name = "TimeStamp", + .cat = "devtools.timeline", + .ph = 'I', + .ts = event.createdAt, + .pid = processId_, + .tid = event.threadId, + .args = folly::dynamic::object( + "data", + folly::dynamic::object( + "name", "ReactNative-ComponentsTrack")( + "start", timestamp)("end", timestamp)( + "track", *event.trackName)), + }); + } + } + if (event.trackName) { data["track"] = std::move(*event.trackName); } diff --git a/packages/react-native/ReactCommon/jsinspector-modern/tracing/PerformanceTracer.h b/packages/react-native/ReactCommon/jsinspector-modern/tracing/PerformanceTracer.h index 81818fb763cb..e93e985525e6 100644 --- a/packages/react-native/ReactCommon/jsinspector-modern/tracing/PerformanceTracer.h +++ b/packages/react-native/ReactCommon/jsinspector-modern/tracing/PerformanceTracer.h @@ -310,6 +310,10 @@ class PerformanceTracer { std::vector* previousBuffer_{}; HighResTimeStamp currentBufferStartTime_; + // A flag that is used to ensure we only emit one auxiliary entry for the + // ordering of Scheduler / Component tracks. + bool alreadyEmittedEntryForComponentsTrackOrdering_ = false; + /** * Protects data members of this class for concurrent access, including * the tracingAtomic_, in order to eliminate potential "logic" races. From e1599b722efeee63c2f3695b684f936aad38d2aa Mon Sep 17 00:00:00 2001 From: Ruslan Lesiutin Date: Fri, 19 Sep 2025 04:27:04 -0700 Subject: [PATCH 2/2] Fix unkown name for Timestamps on Timings track (#53854) Summary: # Changelog: [Internal] This fixes the unkown names message for TimeStamps on Timings track Differential Revision: D82812849 --- .../jsinspector-modern/tracing/PerformanceTracer.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/packages/react-native/ReactCommon/jsinspector-modern/tracing/PerformanceTracer.cpp b/packages/react-native/ReactCommon/jsinspector-modern/tracing/PerformanceTracer.cpp index 3d2f0e80d9eb..8cd38188c346 100644 --- a/packages/react-native/ReactCommon/jsinspector-modern/tracing/PerformanceTracer.cpp +++ b/packages/react-native/ReactCommon/jsinspector-modern/tracing/PerformanceTracer.cpp @@ -551,11 +551,8 @@ void PerformanceTracer::enqueueTraceEventsFromPerformanceTracerEvent( }); }, [&](PerformanceTracerEventTimeStamp&& event) { - // `name` takes precedence over `message` in Chrome DevTools - // Frontend, no need - // to record both. - folly::dynamic data = - folly::dynamic::object("name", std::move(event.name)); + folly::dynamic data = folly::dynamic::object("name", event.name)( + "message", std::move(event.name)); if (event.start) { if (std::holds_alternative(*event.start)) { data["start"] = highResTimeStampToTracingClockTimeStamp(