mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
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
This commit is contained in:
committed by
Facebook GitHub Bot
parent
674fb77d93
commit
6ef351b3ce
@@ -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
|
||||
|
||||
@@ -13,13 +13,11 @@ namespace facebook::react::jsinspector_modern::cdp::network {
|
||||
|
||||
namespace {
|
||||
|
||||
folly::dynamic headersToDynamic(const std::optional<Headers>& 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>& 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,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ using Headers = std::map<std::string, std::string>;
|
||||
struct Request {
|
||||
std::string url;
|
||||
std::string method;
|
||||
std::optional<Headers> headers;
|
||||
Headers headers;
|
||||
std::optional<std::string> 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 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>& headers,
|
||||
const Headers& headers,
|
||||
int encodedDataLength);
|
||||
|
||||
folly::dynamic toDynamic() const;
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
|
||||
namespace facebook::react::jsinspector_modern {
|
||||
|
||||
using Headers = std::map<std::string, std::string>;
|
||||
|
||||
/**
|
||||
* 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<std::string, std::string>& headers);
|
||||
std::string mimeTypeFromHeaders(const Headers& headers);
|
||||
|
||||
} // namespace facebook::react::jsinspector_modern
|
||||
|
||||
@@ -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
|
||||
)
|
||||
|
||||
+82
-19
@@ -9,6 +9,8 @@
|
||||
#include "Timing.h"
|
||||
#include "TraceEventSerializer.h"
|
||||
|
||||
#include <jsinspector-modern/network/CdpNetwork.h>
|
||||
#include <jsinspector-modern/network/HttpUtils.h>
|
||||
#include <oscompat/OSCompat.h>
|
||||
#include <react/timing/primitives.h>
|
||||
|
||||
@@ -16,9 +18,12 @@
|
||||
|
||||
#include <mutex>
|
||||
|
||||
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<std::mutex> 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<std::mutex> 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<std::mutex> 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());
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
|
||||
#include <folly/dynamic.h>
|
||||
#include <atomic>
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
@@ -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<std::string, std::string>;
|
||||
|
||||
/**
|
||||
* [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();
|
||||
|
||||
+1
@@ -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"
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <jsinspector-modern/network/CdpNetwork.h>
|
||||
#include <jsinspector-modern/network/HttpUtils.h>
|
||||
#include <jsinspector-modern/network/NetworkHandler.h>
|
||||
#include <jsinspector-modern/tracing/PerformanceTracer.h>
|
||||
#endif
|
||||
#include <react/featureflags/ReactNativeFeatureFlags.h>
|
||||
#include <react/performance/timeline/PerformanceEntryReporter.h>
|
||||
@@ -35,9 +36,9 @@ void NetworkReporter::reportRequestStart(
|
||||
const RequestInfo& requestInfo,
|
||||
int encodedDataLength,
|
||||
const std::optional<ResponseInfo>& redirectResponse) {
|
||||
if (ReactNativeFeatureFlags::enableResourceTimingAPI()) {
|
||||
auto now = HighResTimeStamp::now();
|
||||
auto now = HighResTimeStamp::now();
|
||||
|
||||
if (ReactNativeFeatureFlags::enableResourceTimingAPI()) {
|
||||
// All builds: Annotate PerformanceResourceTiming metadata
|
||||
{
|
||||
std::lock_guard<std::mutex> 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>& headers) {
|
||||
if (ReactNativeFeatureFlags::enableResourceTimingAPI()) {
|
||||
auto now = HighResTimeStamp::now();
|
||||
auto now = HighResTimeStamp::now();
|
||||
|
||||
if (ReactNativeFeatureFlags::enableResourceTimingAPI()) {
|
||||
// All builds: Annotate PerformanceResourceTiming metadata
|
||||
{
|
||||
std::lock_guard<std::mutex> 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<std::mutex> 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<int>& 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<std::mutex> 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
|
||||
|
||||
@@ -28,8 +28,6 @@ namespace facebook::react {
|
||||
*/
|
||||
struct ResourceTimingData {
|
||||
std::string url;
|
||||
std::string requestMethod;
|
||||
std::optional<std::string> resourceType;
|
||||
HighResTimeStamp fetchStart;
|
||||
HighResTimeStamp requestStart;
|
||||
std::optional<HighResTimeStamp> 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
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
+1
-33
@@ -307,10 +307,7 @@ void PerformanceEntryReporter::reportResourceTiming(
|
||||
std::optional<HighResTimeStamp> connectEnd,
|
||||
HighResTimeStamp responseStart,
|
||||
HighResTimeStamp responseEnd,
|
||||
const std::optional<int>& responseStatus,
|
||||
const std::optional<std::string>& devtoolsRequestId,
|
||||
const std::optional<std::string>& requestMethod,
|
||||
const std::optional<std::string>& resourceType) {
|
||||
const std::optional<int>& 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<std::string>& devtoolsRequestId,
|
||||
const std::optional<std::string>& requestMethod,
|
||||
const std::optional<std::string>& 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
|
||||
|
||||
+1
-4
@@ -118,10 +118,7 @@ class PerformanceEntryReporter {
|
||||
std::optional<HighResTimeStamp> connectEnd,
|
||||
HighResTimeStamp responseStart,
|
||||
HighResTimeStamp responseEnd,
|
||||
const std::optional<int>& responseStatus,
|
||||
const std::optional<std::string>& devtoolsRequestId,
|
||||
const std::optional<std::string>& requestMethod,
|
||||
const std::optional<std::string>& resourceType);
|
||||
const std::optional<int>& responseStatus);
|
||||
|
||||
private:
|
||||
std::unique_ptr<PerformanceObserverRegistry> observerRegistry_;
|
||||
|
||||
Reference in New Issue
Block a user