Emit synthetic Trace Events for non-bridgeless to fix trace representation (#49729)

Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/49729

# Changelog: [Internal]

The only data source for non-bridgeless setup is JavaScript samples.

Chrome DevTools frontend is built around an assumption that thread should have at least single timeline or user timing event to be represented on a timeline view. They do it for filtering out unnecessary workers threads and other.

We will emit 2 synthetic Trace Events that should cover these requirements and recorded traces that contain only JavaScript samples should now be displayed correctly.

This is where trace bounds are calculated - https://github.com/facebookexperimental/rn-chrome-devtools-frontend/blob/3adf51aa915c2deb26f5d373751a15b4d0c8f259/front_end/models/trace/handlers/MetaHandler.ts#L169-L173

Reviewed By: huntie

Differential Revision: D70328681

fbshipit-source-id: 8eca0017d85de9ecbfb49074b439d5c4fee4aa56
This commit is contained in:
Ruslan Lesiutin
2025-02-27 10:38:38 -08:00
committed by Facebook GitHub Bot
parent 13177b3025
commit 8698ecad18
@@ -67,6 +67,21 @@ bool PerformanceTracer::stopTracing() {
return false;
}
// This is synthetic Trace Event, which should not be represented on a
// timeline. CDT is not using Profile or ProfileChunk events for determining
// trace timeline window, this is why trace that only contains JavaScript
// samples will be displayed as empty. We use this event to avoid that.
// This could happen for non-bridgeless apps, where Performance interface is
// not supported and no spec-compliant Event Loop implementation.
buffer_.push_back(TraceEvent{
.name = "ReactNative-TracingStopped",
.cat = "disabled-by-default-devtools.timeline",
.ph = 'I',
.ts = getUnixTimestampOfNow(),
.pid = processId_,
.tid = oscompat::getCurrentThreadId(),
});
performanceMeasureCount_ = 0;
profileCount_ = 0;
tracing_ = false;
@@ -212,6 +227,20 @@ void PerformanceTracer::reportThread(uint64_t id, const std::string& name) {
.tid = id,
.args = folly::dynamic::object("name", name),
});
// This is synthetic Trace Event, which should not be represented on a
// timeline. CDT will filter out threads that only have JavaScript samples and
// no timeline events or user timings. We use this event to avoid that.
// This could happen for non-bridgeless apps, where Performance interface is
// not supported and no spec-compliant Event Loop implementation.
buffer_.push_back(TraceEvent{
.name = "ReactNative-ThreadRegistered",
.cat = "disabled-by-default-devtools.timeline",
.ph = 'I',
.ts = 0,
.pid = processId_,
.tid = id,
});
}
uint16_t PerformanceTracer::reportRuntimeProfile(