From 6ef351b3cea4103c72eb4657aebb5a7a8f1232e7 Mon Sep 17 00:00:00 2001 From: Alex Hunt Date: Thu, 18 Sep 2025 03:01:22 -0700 Subject: [PATCH] Move trace event handling into NetworkReporter (#53776) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/53776 Refactor and improve how we emit CDP trace events for network requests. Key changes: - Split up `PerformanceTracer` methods into discrete trace events. - Move event calls out of `PerformanceEntryReporter` (upwards) into `NetworkReporter`. This now: - Aligns better with the matching source `NetworkReporter` events. - Removes metadata pieces from `PerformanceEntryReporter` that weren't part of the Web `PerformanceResourceTiming` API. - Populate additional fields on `ResourceReceiveResponse`. Changelog: [Internal] Reviewed By: hoxyq Differential Revision: D82433225 fbshipit-source-id: 4fce219f0c86a7257b8df250ef9f2b4ec8bd8de3 --- packages/react-native/Package.swift | 2 +- .../jsinspector-modern/network/CdpNetwork.cpp | 12 +-- .../jsinspector-modern/network/CdpNetwork.h | 6 +- .../jsinspector-modern/network/HttpUtils.h | 5 +- .../jsinspector-modern/tracing/CMakeLists.txt | 1 + .../tracing/PerformanceTracer.cpp | 101 ++++++++++++++---- .../tracing/PerformanceTracer.h | 61 +++++++++-- .../tracing/React-jsinspectortracing.podspec | 1 + .../react/networking/CMakeLists.txt | 2 + .../react/networking/NetworkReporter.cpp | 70 ++++++------ .../react/networking/NetworkReporter.h | 14 +-- .../react/networking/React-networking.podspec | 1 + .../timeline/PerformanceEntryReporter.cpp | 34 +----- .../timeline/PerformanceEntryReporter.h | 5 +- 14 files changed, 200 insertions(+), 115 deletions(-) diff --git a/packages/react-native/Package.swift b/packages/react-native/Package.swift index 4e235e665ab..83eaf65fe53 100644 --- a/packages/react-native/Package.swift +++ b/packages/react-native/Package.swift @@ -161,7 +161,7 @@ let reactJsInspectorTracing = RNTarget( name: .reactJsInspectorTracing, path: "ReactCommon/jsinspector-modern/tracing", excludedPaths: ["tests"], - dependencies: [.reactNativeDependencies, .reactFeatureFlags, .jsi, .reactOSCompat] + dependencies: [.reactNativeDependencies, .reactFeatureFlags, .reactJsInspectorNetwork, .jsi, .reactOSCompat] ) /// React-jsinspectornetwork.podspec diff --git a/packages/react-native/ReactCommon/jsinspector-modern/network/CdpNetwork.cpp b/packages/react-native/ReactCommon/jsinspector-modern/network/CdpNetwork.cpp index 19ed4380eeb..916103327b3 100644 --- a/packages/react-native/ReactCommon/jsinspector-modern/network/CdpNetwork.cpp +++ b/packages/react-native/ReactCommon/jsinspector-modern/network/CdpNetwork.cpp @@ -13,13 +13,11 @@ namespace facebook::react::jsinspector_modern::cdp::network { namespace { -folly::dynamic headersToDynamic(const std::optional& headers) { +folly::dynamic headersToDynamic(const Headers& headers) { folly::dynamic result = folly::dynamic::object; - if (headers) { - for (const auto& [key, value] : *headers) { - result[key] = value; - } + for (const auto& [key, value] : headers) { + result[key] = value; } return result; @@ -41,14 +39,14 @@ folly::dynamic Request::toDynamic() const { /* static */ Response Response::fromInputParams( const std::string& url, uint16_t status, - const std::optional& headers, + const Headers& headers, int encodedDataLength) { return { .url = url, .status = status, .statusText = httpReasonPhrase(status), .headers = headers, - .mimeType = mimeTypeFromHeaders(headers.value_or(Headers())), + .mimeType = mimeTypeFromHeaders(headers), .encodedDataLength = encodedDataLength, }; } diff --git a/packages/react-native/ReactCommon/jsinspector-modern/network/CdpNetwork.h b/packages/react-native/ReactCommon/jsinspector-modern/network/CdpNetwork.h index b22c2979912..156bf56fe8a 100644 --- a/packages/react-native/ReactCommon/jsinspector-modern/network/CdpNetwork.h +++ b/packages/react-native/ReactCommon/jsinspector-modern/network/CdpNetwork.h @@ -24,7 +24,7 @@ using Headers = std::map; struct Request { std::string url; std::string method; - std::optional headers; + Headers headers; std::optional postData; folly::dynamic toDynamic() const; @@ -37,7 +37,7 @@ struct Response { std::string url; uint16_t status; std::string statusText; - std::optional headers; + Headers headers; std::string mimeType; int encodedDataLength; @@ -48,7 +48,7 @@ struct Response { static Response fromInputParams( const std::string& url, uint16_t status, - const std::optional& headers, + const Headers& headers, int encodedDataLength); folly::dynamic toDynamic() const; diff --git a/packages/react-native/ReactCommon/jsinspector-modern/network/HttpUtils.h b/packages/react-native/ReactCommon/jsinspector-modern/network/HttpUtils.h index 5fcd275d12c..3cabf2438a3 100644 --- a/packages/react-native/ReactCommon/jsinspector-modern/network/HttpUtils.h +++ b/packages/react-native/ReactCommon/jsinspector-modern/network/HttpUtils.h @@ -12,6 +12,8 @@ namespace facebook::react::jsinspector_modern { +using Headers = std::map; + /** * Get the HTTP reason phrase for a given status code (RFC 9110). */ @@ -21,7 +23,6 @@ std::string httpReasonPhrase(uint16_t status); * Get the MIME type for a response based on the 'Content-Type' header. If * the header is not present, returns 'application/octet-stream'. */ -std::string mimeTypeFromHeaders( - const std::map& headers); +std::string mimeTypeFromHeaders(const Headers& headers); } // namespace facebook::react::jsinspector_modern diff --git a/packages/react-native/ReactCommon/jsinspector-modern/tracing/CMakeLists.txt b/packages/react-native/ReactCommon/jsinspector-modern/tracing/CMakeLists.txt index 36ea342318c..c7dbdc35215 100644 --- a/packages/react-native/ReactCommon/jsinspector-modern/tracing/CMakeLists.txt +++ b/packages/react-native/ReactCommon/jsinspector-modern/tracing/CMakeLists.txt @@ -18,6 +18,7 @@ target_include_directories(jsinspector_tracing PUBLIC ${REACT_COMMON_DIR}) target_link_libraries(jsinspector_tracing folly_runtime + jsinspector_network oscompat react_timing ) diff --git a/packages/react-native/ReactCommon/jsinspector-modern/tracing/PerformanceTracer.cpp b/packages/react-native/ReactCommon/jsinspector-modern/tracing/PerformanceTracer.cpp index 959525080a0..1dcc559725a 100644 --- a/packages/react-native/ReactCommon/jsinspector-modern/tracing/PerformanceTracer.cpp +++ b/packages/react-native/ReactCommon/jsinspector-modern/tracing/PerformanceTracer.cpp @@ -9,6 +9,8 @@ #include "Timing.h" #include "TraceEventSerializer.h" +#include +#include #include #include @@ -16,9 +18,12 @@ #include +using namespace facebook::react; + namespace facebook::react::jsinspector_modern::tracing { namespace { + /** * Instead of validating that the indicated duration is positive, we can ensure * the value is sensible (less than 1 seccond doesn't make much sense). @@ -31,6 +36,7 @@ ThreadId getCurrentThreadId() { oscompat::getCurrentThreadId(); return CURRENT_THREAD_ID; } + } // namespace PerformanceTracer& PerformanceTracer::getInstance() { @@ -232,15 +238,9 @@ void PerformanceTracer::reportEventLoopMicrotasks( }); } -void PerformanceTracer::reportResourceTiming( - const std::string& requestId, - const std::string& url, - HighResTimeStamp fetchStart, - HighResTimeStamp responseStart, - HighResTimeStamp responseEnd, - int statusCode, - const std::string& requestMethod, - const std::string& resourceType) { +void PerformanceTracer::reportResourceWillSendRequest( + const std::string& devtoolsRequestId, + HighResTimeStamp start) { if (!tracingAtomic_) { return; } @@ -251,27 +251,82 @@ void PerformanceTracer::reportResourceTiming( } enqueueEvent(PerformanceTracerResourceWillSendRequest{ - .requestId = requestId, - .start = fetchStart, + .requestId = devtoolsRequestId, + .start = start, .threadId = getCurrentThreadId(), }); +} + +void PerformanceTracer::reportResourceSendRequest( + const std::string& devtoolsRequestId, + HighResTimeStamp start, + const std::string& url, + const std::string& requestMethod, + const Headers& headers) { + if (!tracingAtomic_) { + return; + } + + std::lock_guard lock(mutex_); + if (!tracingAtomic_) { + return; + } + + auto resourceType = + jsinspector_modern::cdp::network::resourceTypeFromMimeType( + jsinspector_modern::mimeTypeFromHeaders(headers)); enqueueEvent(PerformanceTracerResourceSendRequest{ - .requestId = requestId, + .requestId = devtoolsRequestId, .url = url, - .start = fetchStart, + .start = start, .requestMethod = requestMethod, .resourceType = resourceType, .threadId = getCurrentThreadId(), }); +} + +void PerformanceTracer::reportResourceReceiveResponse( + const std::string& devtoolsRequestId, + HighResTimeStamp start, + int statusCode, + const Headers& headers, + int encodedDataLength) { + if (!tracingAtomic_) { + return; + } + + std::lock_guard lock(mutex_); + if (!tracingAtomic_) { + return; + } + enqueueEvent(PerformanceTracerResourceReceiveResponse{ - .requestId = requestId, - .start = responseStart, + .requestId = devtoolsRequestId, + .start = start, + .encodedDataLength = encodedDataLength, + .headers = headers, + .mimeType = jsinspector_modern::mimeTypeFromHeaders(headers), + .protocol = "h2", .statusCode = statusCode, .threadId = getCurrentThreadId(), }); +} + +void PerformanceTracer::reportResourceFinish( + const std::string& devtoolsRequestId, + HighResTimeStamp start) { + if (!tracingAtomic_) { + return; + } + + std::lock_guard lock(mutex_); + if (!tracingAtomic_) { + return; + } + enqueueEvent(PerformanceTracerResourceFinish{ - .requestId = requestId, - .start = responseEnd, + .requestId = devtoolsRequestId, + .start = start, .threadId = getCurrentThreadId(), }); } @@ -567,7 +622,7 @@ void PerformanceTracer::enqueueTraceEventsFromPerformanceTracerEvent( [&](PerformanceTracerResourceSendRequest&& event) { folly::dynamic data = folly::dynamic::object("initiator", folly::dynamic::object())( - "renderBlocking", "non_blocking")( + "priority", "VeryHigh")("renderBlocking", "non_blocking")( "requestId", std::move(event.requestId))( "requestMethod", std::move(event.requestMethod))( "resourceType", std::move(event.resourceType))( @@ -585,7 +640,15 @@ void PerformanceTracer::enqueueTraceEventsFromPerformanceTracerEvent( }); }, [&](PerformanceTracerResourceReceiveResponse&& event) { - folly::dynamic data = folly::dynamic::object("protocol", "h2")( + folly::dynamic headersEntries = folly::dynamic::array; + for (const auto& [key, value] : event.headers) { + headersEntries.push_back( + folly::dynamic::object("name", key)("value", value)); + } + folly::dynamic data = folly::dynamic::object( + "encodedDataLength", event.encodedDataLength)( + "headers", headersEntries)("mimeType", event.mimeType)( + "protocol", event.protocol)( "requestId", std::move(event.requestId))( "statusCode", event.statusCode)( "timing", folly::dynamic::object()); diff --git a/packages/react-native/ReactCommon/jsinspector-modern/tracing/PerformanceTracer.h b/packages/react-native/ReactCommon/jsinspector-modern/tracing/PerformanceTracer.h index de63396712e..0d4ffee3c0d 100644 --- a/packages/react-native/ReactCommon/jsinspector-modern/tracing/PerformanceTracer.h +++ b/packages/react-native/ReactCommon/jsinspector-modern/tracing/PerformanceTracer.h @@ -15,6 +15,7 @@ #include #include +#include #include #include #include @@ -24,6 +25,8 @@ namespace facebook::react::jsinspector_modern::tracing { // TODO: Review how this API is integrated into jsinspector_modern (singleton // design is copied from earlier FuseboxTracer prototype). +using Headers = std::map; + /** * [Experimental] An interface for logging performance trace events to the * modern debugger server. @@ -109,19 +112,53 @@ class PerformanceTracer { void reportEventLoopMicrotasks(HighResTimeStamp start, HighResTimeStamp end); /** - * Record a "ResourceSendRequest"/"ResourceFinish" event pair - a labelled - * duration in the Performance timeline Network track. If not currently - * tracing, this is a no-op. + * Record a "ResourceWillSendRequest" event. Paired with other "Resource*" + * events, renders a network request timeline in the Performance panel Network + * track. + * + * If not currently tracing, this is a no-op. */ - void reportResourceTiming( - const std::string& requestId, + void reportResourceWillSendRequest( + const std::string& devtoolsRequestId, + HighResTimeStamp start); + + /** + * Record a "ResourceSendRequest" event. Paired with other "Resource*" + * events, renders a network request timeline in the Performance panel Network + * track. + * + * If not currently tracing, this is a no-op. + */ + void reportResourceSendRequest( + const std::string& devtoolsRequestId, + HighResTimeStamp start, const std::string& url, - HighResTimeStamp fetchStart, - HighResTimeStamp responseStart, - HighResTimeStamp responseEnd, - int statusCode, const std::string& requestMethod, - const std::string& resourceType); + const Headers& headers); + + /** + * Record a "ResourceReceiveResponse" event. Paired with other "Resource*" + * events, renders a network request timeline in the Performance panel Network + * track. + * + * If not currently tracing, this is a no-op. + */ + void reportResourceReceiveResponse( + const std::string& devtoolsRequestId, + HighResTimeStamp start, + int statusCode, + const Headers& headers, + int encodedDataLength); + + /** + * Record a "ResourceFinish" event. Paired with other "Resource*" events, + * renders a network request timeline in the Performance panel Network track. + * + * If not currently tracing, this is a no-op. + */ + void reportResourceFinish( + const std::string& devtoolsRequestId, + HighResTimeStamp start); /** * Creates "Profile" Trace Event. @@ -223,6 +260,10 @@ class PerformanceTracer { struct PerformanceTracerResourceReceiveResponse { std::string requestId; HighResTimeStamp start; + int encodedDataLength; + Headers headers; + std::string mimeType; + std::string protocol; int statusCode; ThreadId threadId; HighResTimeStamp createdAt = HighResTimeStamp::now(); diff --git a/packages/react-native/ReactCommon/jsinspector-modern/tracing/React-jsinspectortracing.podspec b/packages/react-native/ReactCommon/jsinspector-modern/tracing/React-jsinspectortracing.podspec index 8e3c2d61b93..5f2e5dbc58c 100644 --- a/packages/react-native/ReactCommon/jsinspector-modern/tracing/React-jsinspectortracing.podspec +++ b/packages/react-native/ReactCommon/jsinspector-modern/tracing/React-jsinspectortracing.podspec @@ -43,6 +43,7 @@ Pod::Spec.new do |s| resolve_use_frameworks(s, header_mappings_dir: "../..", module_name: module_name) + add_dependency(s, "React-jsinspectornetwork", :framework_name => 'jsinspector_modernnetwork') s.dependency "React-oscompat" s.dependency "React-timing" diff --git a/packages/react-native/ReactCommon/react/networking/CMakeLists.txt b/packages/react-native/ReactCommon/react/networking/CMakeLists.txt index eee155065bb..345cd3c079d 100644 --- a/packages/react-native/ReactCommon/react/networking/CMakeLists.txt +++ b/packages/react-native/ReactCommon/react/networking/CMakeLists.txt @@ -17,5 +17,7 @@ target_compile_options(react_networking PRIVATE -Wpedantic) target_include_directories(react_networking PUBLIC ${REACT_COMMON_DIR}) target_link_libraries(react_networking folly_runtime + jsinspector_network + jsinspector_tracing react_performance_timeline react_timing) diff --git a/packages/react-native/ReactCommon/react/networking/NetworkReporter.cpp b/packages/react-native/ReactCommon/react/networking/NetworkReporter.cpp index 16951912db4..fbc34603753 100644 --- a/packages/react-native/ReactCommon/react/networking/NetworkReporter.cpp +++ b/packages/react-native/ReactCommon/react/networking/NetworkReporter.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #endif #include #include @@ -35,9 +36,9 @@ void NetworkReporter::reportRequestStart( const RequestInfo& requestInfo, int encodedDataLength, const std::optional& redirectResponse) { - if (ReactNativeFeatureFlags::enableResourceTimingAPI()) { - auto now = HighResTimeStamp::now(); + auto now = HighResTimeStamp::now(); + if (ReactNativeFeatureFlags::enableResourceTimingAPI()) { // All builds: Annotate PerformanceResourceTiming metadata { std::lock_guard lock(perfTimingsMutex_); @@ -45,7 +46,6 @@ void NetworkReporter::reportRequestStart( requestId, ResourceTimingData{ .url = requestInfo.url, - .requestMethod = requestInfo.httpMethod, .fetchStart = now, .requestStart = now, }); @@ -53,13 +53,15 @@ void NetworkReporter::reportRequestStart( } #ifdef REACT_NATIVE_DEBUGGER_ENABLED - // Debug build: CDP event handling + auto headers = requestInfo.headers.value_or(Headers{}); + + // Debugger enabled: CDP event handling jsinspector_modern::NetworkHandler::getInstance().onRequestWillBeSent( requestId, { .url = requestInfo.url, .method = requestInfo.httpMethod, - .headers = requestInfo.headers, + .headers = headers, .postData = requestInfo.httpBody, }, redirectResponse.has_value() @@ -67,18 +69,25 @@ void NetworkReporter::reportRequestStart( jsinspector_modern::cdp::network::Response::fromInputParams( redirectResponse->url, redirectResponse->statusCode, - redirectResponse->headers, + redirectResponse->headers.value_or(Headers{}), encodedDataLength)) : std::nullopt); + + // Debugger enabled: Add trace events to Performance timeline + auto& performanceTracer = + jsinspector_modern::tracing::PerformanceTracer::getInstance(); + performanceTracer.reportResourceWillSendRequest(requestId, now); + performanceTracer.reportResourceSendRequest( + requestId, now, requestInfo.url, requestInfo.httpMethod, headers); #endif } void NetworkReporter::reportConnectionTiming( const std::string& requestId, const std::optional& headers) { - if (ReactNativeFeatureFlags::enableResourceTimingAPI()) { - auto now = HighResTimeStamp::now(); + auto now = HighResTimeStamp::now(); + if (ReactNativeFeatureFlags::enableResourceTimingAPI()) { // All builds: Annotate PerformanceResourceTiming metadata { std::lock_guard lock(perfTimingsMutex_); @@ -90,7 +99,7 @@ void NetworkReporter::reportConnectionTiming( } #ifdef REACT_NATIVE_DEBUGGER_ENABLED - // Debug build: CDP event handling + // Debugger enabled: CDP event handling jsinspector_modern::NetworkHandler::getInstance() .onRequestWillBeSentExtraInfo(requestId, headers.value_or(Headers{})); #endif @@ -100,9 +109,9 @@ void NetworkReporter::reportResponseStart( const std::string& requestId, const ResponseInfo& responseInfo, int encodedDataLength) { - if (ReactNativeFeatureFlags::enableResourceTimingAPI()) { - auto now = HighResTimeStamp::now(); + auto now = HighResTimeStamp::now(); + if (ReactNativeFeatureFlags::enableResourceTimingAPI()) { // All builds: Annotate PerformanceResourceTiming metadata { std::lock_guard lock(perfTimingsMutex_); @@ -111,26 +120,26 @@ void NetworkReporter::reportResponseStart( it->second.connectEnd = now; it->second.responseStart = now; it->second.responseStatus = responseInfo.statusCode; -#ifdef REACT_NATIVE_DEBUGGER_ENABLED - // Debug build: Compute additional fields to send in CDP trace events - it->second.resourceType = - jsinspector_modern::cdp::network::resourceTypeFromMimeType( - jsinspector_modern::mimeTypeFromHeaders( - responseInfo.headers.value_or(Headers{}))); -#endif } } } #ifdef REACT_NATIVE_DEBUGGER_ENABLED - // Debug build: CDP event handling + auto headers = responseInfo.headers.value_or(Headers{}); + + // Debugger enabled: CDP event handling jsinspector_modern::NetworkHandler::getInstance().onResponseReceived( requestId, jsinspector_modern::cdp::network::Response::fromInputParams( responseInfo.url, responseInfo.statusCode, - responseInfo.headers, + headers, encodedDataLength)); + + // Debugger enabled: Add trace event to Performance timeline + jsinspector_modern::tracing::PerformanceTracer::getInstance() + .reportResourceReceiveResponse( + requestId, now, responseInfo.statusCode, headers, encodedDataLength); #endif } @@ -139,7 +148,7 @@ void NetworkReporter::reportDataReceived( int dataLength, const std::optional& encodedDataLength) { #ifdef REACT_NATIVE_DEBUGGER_ENABLED - // Debug build: CDP event handling + // Debugger enabled: CDP event handling jsinspector_modern::NetworkHandler::getInstance().onDataReceived( requestId, dataLength, encodedDataLength.value_or(dataLength)); #endif @@ -148,9 +157,9 @@ void NetworkReporter::reportDataReceived( void NetworkReporter::reportResponseEnd( const std::string& requestId, int encodedDataLength) { - if (ReactNativeFeatureFlags::enableResourceTimingAPI()) { - auto now = HighResTimeStamp::now(); + auto now = HighResTimeStamp::now(); + if (ReactNativeFeatureFlags::enableResourceTimingAPI()) { // All builds: Report PerformanceResourceTiming event { std::lock_guard lock(perfTimingsMutex_); @@ -165,19 +174,20 @@ void NetworkReporter::reportResponseEnd( eventData.connectEnd.value_or(now), eventData.responseStart.value_or(now), now, - eventData.responseStatus, - requestId, - eventData.requestMethod, - eventData.resourceType); + eventData.responseStatus); perfTimingsBuffer_.erase(requestId); } } } #ifdef REACT_NATIVE_DEBUGGER_ENABLED - // Debug build: CDP event handling + // Debugger enabled: CDP event handling jsinspector_modern::NetworkHandler::getInstance().onLoadingFinished( requestId, encodedDataLength); + + // Debugger enabled: Add trace event to Performance timeline + jsinspector_modern::tracing::PerformanceTracer::getInstance() + .reportResourceFinish(requestId, now); #endif } @@ -185,7 +195,7 @@ void NetworkReporter::reportRequestFailed( const std::string& requestId, bool cancelled) const { #ifdef REACT_NATIVE_DEBUGGER_ENABLED - // Debug build: CDP event handling + // Debugger enabled: CDP event handling jsinspector_modern::NetworkHandler::getInstance().onLoadingFailed( requestId, cancelled); #endif @@ -196,7 +206,7 @@ void NetworkReporter::storeResponseBody( std::string_view body, bool base64Encoded) { #ifdef REACT_NATIVE_DEBUGGER_ENABLED - // Debug build: Store fetched response body for later CDP retrieval + // Debugger enabled: Store fetched response body for later CDP retrieval jsinspector_modern::NetworkHandler::getInstance().storeResponseBody( requestId, body, base64Encoded); #endif diff --git a/packages/react-native/ReactCommon/react/networking/NetworkReporter.h b/packages/react-native/ReactCommon/react/networking/NetworkReporter.h index a3441771707..1aaa11082a1 100644 --- a/packages/react-native/ReactCommon/react/networking/NetworkReporter.h +++ b/packages/react-native/ReactCommon/react/networking/NetworkReporter.h @@ -28,8 +28,6 @@ namespace facebook::react { */ struct ResourceTimingData { std::string url; - std::string requestMethod; - std::optional resourceType; HighResTimeStamp fetchStart; HighResTimeStamp requestStart; std::optional connectStart; @@ -56,7 +54,8 @@ class NetworkReporter { /** * Report a network request that is about to be sent. * - * - Corresponds to `Network.requestWillBeSent` in CDP. + * - Corresponds to `Network.requestWillBeSent` and the + * "ResourceWillSendRequest" trace event in CDP. * - Corresponds to `PerformanceResourceTiming.requestStart` (specifically, * marking when the native request was initiated). * @@ -72,7 +71,8 @@ class NetworkReporter { * Report timestamp for sending the network request, and (in a debug build) * provide final headers to be reported via CDP. * - * - Corresponds to `Network.requestWillBeSentExtraInfo` in CDP. + * - Corresponds to `Network.requestWillBeSentExtraInfo` and the + * "ResourceSendRequest" trace event in CDP. * - Corresponds to `PerformanceResourceTiming.domainLookupStart`, * `PerformanceResourceTiming.connectStart`. Defined as "immediately before * the browser starts to establish the connection to the server". @@ -87,7 +87,8 @@ class NetworkReporter { * Report when HTTP response headers have been received, corresponding to * when the first byte of the response is available. * - * - Corresponds to `Network.responseReceived` in CDP. + * - Corresponds to `Network.responseReceived` and the + * "ResourceReceiveResponse" trace event in CDP. * - Corresponds to `PerformanceResourceTiming.responseStart`. * * https://w3c.github.io/resource-timing/#dom-performanceresourcetiming-responsestart @@ -112,7 +113,8 @@ class NetworkReporter { * Report when a network request is complete and we are no longer receiving * response data. * - * - Corresponds to `Network.loadingFinished` in CDP. + * - Corresponds to `Network.loadingFinished` and the "ResourceFinish" trace + * event in CDP. * - Corresponds to `PerformanceResourceTiming.responseEnd`. * * https://w3c.github.io/resource-timing/#dom-performanceresourcetiming-responseend diff --git a/packages/react-native/ReactCommon/react/networking/React-networking.podspec b/packages/react-native/ReactCommon/react/networking/React-networking.podspec index 233bdf981ee..a7711b66820 100644 --- a/packages/react-native/ReactCommon/react/networking/React-networking.podspec +++ b/packages/react-native/ReactCommon/react/networking/React-networking.podspec @@ -43,6 +43,7 @@ Pod::Spec.new do |s| end add_dependency(s, "React-featureflags") add_dependency(s, "React-jsinspectornetwork", :framework_name => 'jsinspector_modernnetwork') + add_dependency(s, "React-jsinspectortracing", :framework_name => 'jsinspector_moderntracing') s.dependency "React-performancetimeline" s.dependency "React-timing" diff --git a/packages/react-native/ReactCommon/react/performance/timeline/PerformanceEntryReporter.cpp b/packages/react-native/ReactCommon/react/performance/timeline/PerformanceEntryReporter.cpp index 117f966dbbc..d4c6423b231 100644 --- a/packages/react-native/ReactCommon/react/performance/timeline/PerformanceEntryReporter.cpp +++ b/packages/react-native/ReactCommon/react/performance/timeline/PerformanceEntryReporter.cpp @@ -307,10 +307,7 @@ void PerformanceEntryReporter::reportResourceTiming( std::optional connectEnd, HighResTimeStamp responseStart, HighResTimeStamp responseEnd, - const std::optional& responseStatus, - const std::optional& devtoolsRequestId, - const std::optional& requestMethod, - const std::optional& resourceType) { + const std::optional& responseStatus) { const auto entry = PerformanceResourceTiming{ {.name = url, .startTime = fetchStart}, fetchStart, @@ -322,8 +319,6 @@ void PerformanceEntryReporter::reportResourceTiming( responseStatus, }; - traceResourceTiming(entry, devtoolsRequestId, requestMethod, resourceType); - // Add to buffers & notify observers { std::unique_lock lock(buffersMutex_); @@ -375,31 +370,4 @@ void PerformanceEntryReporter::traceMeasure( } } -void PerformanceEntryReporter::traceResourceTiming( - const PerformanceResourceTiming& entry, - const std::optional& devtoolsRequestId, - const std::optional& requestMethod, - const std::optional& resourceType) const { - if (!entry.responseStart.has_value() || !entry.responseEnd.has_value() || - !entry.responseStatus.has_value() || !devtoolsRequestId.has_value() || - !requestMethod.has_value() || !resourceType.has_value()) { - return; - } - - auto& performanceTracer = - jsinspector_modern::tracing::PerformanceTracer::getInstance(); - - if (performanceTracer.isTracing()) { - performanceTracer.reportResourceTiming( - *devtoolsRequestId, - entry.name, - entry.fetchStart, - *entry.responseStart, - *entry.responseEnd, - *entry.responseStatus, - *requestMethod, - *resourceType); - } -} - } // namespace facebook::react diff --git a/packages/react-native/ReactCommon/react/performance/timeline/PerformanceEntryReporter.h b/packages/react-native/ReactCommon/react/performance/timeline/PerformanceEntryReporter.h index 8ae2af0d24c..938f3fcb2f8 100644 --- a/packages/react-native/ReactCommon/react/performance/timeline/PerformanceEntryReporter.h +++ b/packages/react-native/ReactCommon/react/performance/timeline/PerformanceEntryReporter.h @@ -118,10 +118,7 @@ class PerformanceEntryReporter { std::optional connectEnd, HighResTimeStamp responseStart, HighResTimeStamp responseEnd, - const std::optional& responseStatus, - const std::optional& devtoolsRequestId, - const std::optional& requestMethod, - const std::optional& resourceType); + const std::optional& responseStatus); private: std::unique_ptr observerRegistry_;