diff --git a/packages/react-native/ReactCommon/jsinspector-modern/tracing/PerformanceTracer.cpp b/packages/react-native/ReactCommon/jsinspector-modern/tracing/PerformanceTracer.cpp index 7ea2a93df276..8cd38188c346 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); } @@ -550,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( @@ -571,6 +569,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.