Skip to content

Commit c400b88

Browse files
emily8rownmeta-codesync[bot]
authored andcommitted
Add ResourceReceivedData trace event for Performance timeline (#54870)
Summary: Pull Request resolved: #54870 Changelog: [General][Added] - Add ResourceReceivedData trace events for network data chunks in Performance timeline Wire up `NetworkReporter::reportDataReceived` to emit `ResourceReceivedData` trace events for the React Native DevTools Performance panel. This adds a new trace event type that captures when chunked response data is received during network requests. The event is emitted when React Native treats a response as incremental/chunked (when `incrementalUpdates && responseType == "text"`), matching the existing behavior of CDP's `Network.dataReceived` event. The implementation follows the same pattern as the existing `ResourceSendRequest`, `ResourceReceiveResponse`, and `ResourceFinish` events in PerformanceTracer. Reviewed By: huntie Differential Revision: D89050646 fbshipit-source-id: 99bf1fc85e8f27555976d80fee29db54af9b7451
1 parent c16eb23 commit c400b88

4 files changed

Lines changed: 82 additions & 0 deletions

File tree

packages/react-native/ReactCommon/jsinspector-modern/tests/NetworkReporterTest.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -653,6 +653,13 @@ TEST_P(
653653
AtJsonPtr("/params/response/encodedDataLength", 1024),
654654
AtJsonPtr("/params/hasExtraInfo", false))));
655655

656+
this->expectMessageFromPage(JsonParsed(AllOf(
657+
AtJsonPtr("/method", "Network.dataReceived"),
658+
AtJsonPtr("/params/requestId", "trace-events-request"),
659+
AtJsonPtr("/params/timestamp", Gt(0)),
660+
AtJsonPtr("/params/dataLength", 512),
661+
AtJsonPtr("/params/encodedDataLength", 512))));
662+
656663
this->expectMessageFromPage(JsonParsed(AllOf(
657664
AtJsonPtr("/method", "Network.loadingFinished"),
658665
AtJsonPtr("/params/requestId", "trace-events-request"),
@@ -682,6 +689,9 @@ TEST_P(
682689
},
683690
1024);
684691

692+
NetworkReporter::getInstance().reportDataReceived(
693+
"trace-events-request", 512, 512);
694+
685695
NetworkReporter::getInstance().reportResponseEnd(
686696
"trace-events-request", 1024);
687697

@@ -731,6 +741,18 @@ TEST_P(
731741
AtJsonPtr("/receiveHeadersStart", Ge(0)),
732742
AtJsonPtr("/receiveHeadersEnd", Ge(0)))))));
733743

744+
EXPECT_THAT(
745+
allTraceEvents,
746+
Contains(AllOf(
747+
AtJsonPtr("/name", "ResourceReceivedData"),
748+
AtJsonPtr("/cat", "devtools.timeline"),
749+
AtJsonPtr("/ph", "I"),
750+
AtJsonPtr("/s", "t"),
751+
AtJsonPtr("/tid", oscompat::getCurrentThreadId()),
752+
AtJsonPtr("/pid", oscompat::getCurrentProcessId()),
753+
AtJsonPtr("/args/data/requestId", "trace-events-request"),
754+
AtJsonPtr("/args/data/encodedDataLength", 512))));
755+
734756
EXPECT_THAT(
735757
allTraceEvents,
736758
Contains(AllOf(

packages/react-native/ReactCommon/jsinspector-modern/tracing/PerformanceTracer.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,27 @@ void PerformanceTracer::reportResourceSendRequest(
312312
});
313313
}
314314

315+
void PerformanceTracer::reportResourceReceivedData(
316+
const std::string& devtoolsRequestId,
317+
HighResTimeStamp start,
318+
int encodedDataLength) {
319+
if (!tracingAtomic_) {
320+
return;
321+
};
322+
323+
std::lock_guard<std::mutex> lock(mutex_);
324+
if (!tracingAtomic_) {
325+
return;
326+
}
327+
328+
enqueueEvent(
329+
PerformanceTracerResourceReceivedData{
330+
.requestId = devtoolsRequestId,
331+
.start = start,
332+
.encodedDataLength = encodedDataLength,
333+
.threadId = getCurrentThreadId()});
334+
}
335+
315336
void PerformanceTracer::reportResourceReceiveResponse(
316337
const std::string& devtoolsRequestId,
317338
HighResTimeStamp start,
@@ -706,6 +727,23 @@ void PerformanceTracer::enqueueTraceEventsFromPerformanceTracerEvent(
706727
.args = folly::dynamic::object("data", std::move(data)),
707728
});
708729
},
730+
[&](PerformanceTracerResourceReceivedData&& event) {
731+
folly::dynamic data = folly::dynamic::object(
732+
"encodedDataLength", event.encodedDataLength)(
733+
"requestId", std::move(event.requestId));
734+
735+
events.emplace_back(
736+
TraceEvent{
737+
.name = "ResourceReceivedData",
738+
.cat = {Category::Timeline},
739+
.ph = 'I',
740+
.ts = event.start,
741+
.pid = processId_,
742+
.s = 't',
743+
.tid = event.threadId,
744+
.args = folly::dynamic::object("data", std::move(data)),
745+
});
746+
},
709747
[&](PerformanceTracerResourceReceiveResponse&& event) {
710748
folly::dynamic headersEntries = folly::dynamic::array;
711749
for (const auto& [key, value] : event.headers) {

packages/react-native/ReactCommon/jsinspector-modern/tracing/PerformanceTracer.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,12 @@ class PerformanceTracer {
136136
const std::string &requestMethod,
137137
const Headers &headers);
138138

139+
/**
140+
* Record a "ResourceReceivedData" event.
141+
* If not currently tracing, this is a no-op.
142+
*/
143+
void reportResourceReceivedData(const std::string &devtoolsRequestId, HighResTimeStamp start, int encodedDataLength);
144+
139145
/**
140146
* Record a "ResourceReceiveResponse" event. Paired with other "Resource*"
141147
* events, renders a network request timeline in the Performance panel Network
@@ -281,6 +287,14 @@ class PerformanceTracer {
281287
HighResTimeStamp createdAt = HighResTimeStamp::now();
282288
};
283289

290+
struct PerformanceTracerResourceReceivedData {
291+
std::string requestId;
292+
HighResTimeStamp start;
293+
int encodedDataLength;
294+
ThreadId threadId;
295+
HighResTimeStamp createdAt = HighResTimeStamp::now();
296+
};
297+
284298
struct PerformanceTracerResourceReceiveResponse {
285299
std::string requestId;
286300
HighResTimeStamp start;
@@ -302,6 +316,7 @@ class PerformanceTracer {
302316
PerformanceTracerEventMeasure,
303317
PerformanceTracerResourceSendRequest,
304318
PerformanceTracerResourceReceiveResponse,
319+
PerformanceTracerResourceReceivedData,
305320
PerformanceTracerResourceFinish>;
306321

307322
#pragma mark - Private fields and methods

packages/react-native/ReactCommon/react/networking/NetworkReporter.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,9 +168,16 @@ void NetworkReporter::reportDataReceived(
168168
int dataLength,
169169
const std::optional<int>& encodedDataLength) {
170170
#ifdef REACT_NATIVE_DEBUGGER_ENABLED
171+
auto now = HighResTimeStamp::now();
172+
171173
// Debugger enabled: CDP event handling
172174
jsinspector_modern::NetworkHandler::getInstance().onDataReceived(
173175
requestId, dataLength, encodedDataLength.value_or(dataLength));
176+
177+
// Debugger enabled: Add trace event to Performance timeline
178+
jsinspector_modern::tracing::PerformanceTracer::getInstance()
179+
.reportResourceReceivedData(
180+
requestId, now, encodedDataLength.value_or(dataLength));
174181
#endif
175182
}
176183

0 commit comments

Comments
 (0)