mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Revert D72649815: Replace DOMHighResTimeStamp alias in ReactCommon with new abstractions
Differential Revision: D72649815 Original commit changeset: 96bcfaf909d4 Original Phabricator Diff: D72649815 fbshipit-source-id: 491579e20fed41f0f31639f51d6051022ae9de55
This commit is contained in:
committed by
Facebook GitHub Bot
parent
cbfa2ecc9a
commit
65ef8fe6b8
@@ -10,8 +10,10 @@
|
||||
#include "RAMBundleRegistry.h"
|
||||
|
||||
#include <jsinspector-modern/ReactCdp.h>
|
||||
#include <react/timing/primitives.h>
|
||||
|
||||
#include <array>
|
||||
#include <chrono>
|
||||
|
||||
namespace facebook::react {
|
||||
|
||||
@@ -27,8 +29,8 @@ std::string JSExecutor::getSyntheticBundlePath(
|
||||
return buffer.data();
|
||||
}
|
||||
|
||||
HighResTimeStamp JSExecutor::performanceNow() {
|
||||
return HighResTimeStamp::now();
|
||||
double JSExecutor::performanceNow() {
|
||||
return chronoToDOMHighResTimeStamp(std::chrono::steady_clock::now());
|
||||
}
|
||||
|
||||
jsinspector_modern::RuntimeTargetDelegate&
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
#include <folly/dynamic.h>
|
||||
#include <jsinspector-modern/InspectorInterfaces.h>
|
||||
#include <jsinspector-modern/ReactCdp.h>
|
||||
#include <react/timing/primitives.h>
|
||||
|
||||
#ifndef RN_EXPORT
|
||||
#define RN_EXPORT __attribute__((visibility("default")))
|
||||
@@ -139,7 +138,7 @@ class RN_EXPORT JSExecutor {
|
||||
uint32_t bundleId,
|
||||
const std::string& bundlePath);
|
||||
|
||||
static HighResTimeStamp performanceNow();
|
||||
static double performanceNow();
|
||||
|
||||
/**
|
||||
* Get a reference to the \c RuntimeTargetDelegate owned (or implemented) by
|
||||
|
||||
@@ -556,9 +556,7 @@ void bindNativePerformanceNow(Runtime& runtime) {
|
||||
[](jsi::Runtime& runtime,
|
||||
const jsi::Value&,
|
||||
const jsi::Value* args,
|
||||
size_t /*count*/) {
|
||||
return JSExecutor::performanceNow().toDOMHighResTimeStamp();
|
||||
}));
|
||||
size_t count) { return Value(JSExecutor::performanceNow()); }));
|
||||
}
|
||||
|
||||
} // namespace facebook::react
|
||||
|
||||
@@ -78,7 +78,7 @@ void NetworkReporter::reportRequestStart(
|
||||
int encodedDataLength,
|
||||
const std::optional<ResponseInfo>& redirectResponse) {
|
||||
if (ReactNativeFeatureFlags::enableResourceTimingAPI()) {
|
||||
auto now = PerformanceEntryReporter::getInstance()->getCurrentTimeStamp();
|
||||
double now = PerformanceEntryReporter::getInstance()->getCurrentTimeStamp();
|
||||
|
||||
// All builds: Annotate PerformanceResourceTiming metadata
|
||||
{
|
||||
@@ -127,7 +127,7 @@ void NetworkReporter::reportRequestStart(
|
||||
|
||||
void NetworkReporter::reportConnectionTiming(const std::string& requestId) {
|
||||
if (ReactNativeFeatureFlags::enableResourceTimingAPI()) {
|
||||
auto now = PerformanceEntryReporter::getInstance()->getCurrentTimeStamp();
|
||||
double now = PerformanceEntryReporter::getInstance()->getCurrentTimeStamp();
|
||||
|
||||
// All builds: Annotate PerformanceResourceTiming metadata
|
||||
{
|
||||
@@ -168,7 +168,7 @@ void NetworkReporter::reportResponseStart(
|
||||
const ResponseInfo& responseInfo,
|
||||
int encodedDataLength) {
|
||||
if (ReactNativeFeatureFlags::enableResourceTimingAPI()) {
|
||||
auto now = PerformanceEntryReporter::getInstance()->getCurrentTimeStamp();
|
||||
double now = PerformanceEntryReporter::getInstance()->getCurrentTimeStamp();
|
||||
|
||||
// All builds: Annotate PerformanceResourceTiming metadata
|
||||
{
|
||||
@@ -205,7 +205,7 @@ void NetworkReporter::reportResponseStart(
|
||||
|
||||
void NetworkReporter::reportDataReceived(const std::string& requestId) {
|
||||
if (ReactNativeFeatureFlags::enableResourceTimingAPI()) {
|
||||
auto now = PerformanceEntryReporter::getInstance()->getCurrentTimeStamp();
|
||||
double now = PerformanceEntryReporter::getInstance()->getCurrentTimeStamp();
|
||||
|
||||
// All builds: Annotate PerformanceResourceTiming metadata
|
||||
{
|
||||
@@ -233,7 +233,7 @@ void NetworkReporter::reportResponseEnd(
|
||||
const std::string& requestId,
|
||||
int encodedDataLength) {
|
||||
if (ReactNativeFeatureFlags::enableResourceTimingAPI()) {
|
||||
auto now = PerformanceEntryReporter::getInstance()->getCurrentTimeStamp();
|
||||
double now = PerformanceEntryReporter::getInstance()->getCurrentTimeStamp();
|
||||
|
||||
// All builds: Report PerformanceResourceTiming event
|
||||
{
|
||||
|
||||
@@ -35,11 +35,11 @@ using FrontendChannel = std::function<void(std::string_view messageJson)>;
|
||||
*/
|
||||
struct ResourceTimingData {
|
||||
std::string url;
|
||||
HighResTimeStamp fetchStart;
|
||||
HighResTimeStamp requestStart;
|
||||
std::optional<HighResTimeStamp> connectStart;
|
||||
std::optional<HighResTimeStamp> connectEnd;
|
||||
std::optional<HighResTimeStamp> responseStart;
|
||||
DOMHighResTimeStamp fetchStart;
|
||||
DOMHighResTimeStamp requestStart;
|
||||
std::optional<DOMHighResTimeStamp> connectStart;
|
||||
std::optional<DOMHighResTimeStamp> connectEnd;
|
||||
std::optional<DOMHighResTimeStamp> responseStart;
|
||||
std::optional<int> responseStatus;
|
||||
};
|
||||
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
#include "EventLoopReporter.h"
|
||||
|
||||
#if defined(REACT_NATIVE_DEBUGGER_ENABLED)
|
||||
#include <react/timing/primitives.h>
|
||||
#include "PerformanceTracer.h"
|
||||
#endif
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
#include "Timing.h"
|
||||
|
||||
#include <oscompat/OSCompat.h>
|
||||
#include <react/timing/primitives.h>
|
||||
|
||||
#include <folly/json.h>
|
||||
|
||||
|
||||
@@ -13,8 +13,6 @@
|
||||
|
||||
#include <react/timing/primitives.h>
|
||||
|
||||
#include <react/timing/primitives.h>
|
||||
|
||||
#include <folly/dynamic.h>
|
||||
#include <functional>
|
||||
#include <mutex>
|
||||
|
||||
@@ -784,7 +784,7 @@ TEST_F(BridgingTest, highResTimeStampTest) {
|
||||
bridging::fromJs<HighResTimeStamp>(
|
||||
rt, bridging::toJs(rt, timestamp), invoker));
|
||||
|
||||
auto duration = HighResDuration::fromNanoseconds(1);
|
||||
HighResDuration duration = HighResDuration::fromNanoseconds(1);
|
||||
EXPECT_EQ(
|
||||
duration,
|
||||
bridging::fromJs<HighResDuration>(
|
||||
|
||||
+1
-1
@@ -51,7 +51,7 @@ using NativeIntersectionObserverEntry =
|
||||
// isIntersectingAboveThresholds
|
||||
bool,
|
||||
// time
|
||||
HighResTimeStamp>;
|
||||
double>;
|
||||
|
||||
template <>
|
||||
struct Bridging<NativeIntersectionObserverEntry>
|
||||
|
||||
+10
-12
@@ -116,31 +116,30 @@ std::shared_ptr<PerformanceObserver> tryGetObserver(
|
||||
NativePerformance::NativePerformance(std::shared_ptr<CallInvoker> jsInvoker)
|
||||
: NativePerformanceCxxSpec(std::move(jsInvoker)) {}
|
||||
|
||||
HighResTimeStamp NativePerformance::now(jsi::Runtime& /*rt*/) {
|
||||
double NativePerformance::now(jsi::Runtime& /*rt*/) {
|
||||
return JSExecutor::performanceNow();
|
||||
}
|
||||
|
||||
HighResTimeStamp NativePerformance::markWithResult(
|
||||
double NativePerformance::markWithResult(
|
||||
jsi::Runtime& rt,
|
||||
std::string name,
|
||||
std::optional<HighResTimeStamp> startTime) {
|
||||
std::optional<double> startTime) {
|
||||
auto entry =
|
||||
PerformanceEntryReporter::getInstance()->reportMark(name, startTime);
|
||||
return entry.startTime;
|
||||
}
|
||||
|
||||
std::tuple<HighResTimeStamp, HighResDuration>
|
||||
NativePerformance::measureWithResult(
|
||||
std::tuple<double, double> NativePerformance::measureWithResult(
|
||||
jsi::Runtime& runtime,
|
||||
std::string name,
|
||||
HighResTimeStamp startTime,
|
||||
HighResTimeStamp endTime,
|
||||
std::optional<HighResDuration> duration,
|
||||
double startTime,
|
||||
double endTime,
|
||||
std::optional<double> duration,
|
||||
std::optional<std::string> startMark,
|
||||
std::optional<std::string> endMark) {
|
||||
auto reporter = PerformanceEntryReporter::getInstance();
|
||||
|
||||
HighResTimeStamp startTimeValue = startTime;
|
||||
DOMHighResTimeStamp startTimeValue = startTime;
|
||||
// If the start time mark name is specified, it takes precedence over the
|
||||
// startTime parameter, which can be set to 0 by default from JavaScript.
|
||||
if (startMark) {
|
||||
@@ -152,7 +151,7 @@ NativePerformance::measureWithResult(
|
||||
}
|
||||
}
|
||||
|
||||
HighResTimeStamp endTimeValue = endTime;
|
||||
DOMHighResTimeStamp endTimeValue = endTime;
|
||||
// If the end time mark name is specified, it takes precedence over the
|
||||
// startTime parameter, which can be set to 0 by default from JavaScript.
|
||||
if (endMark) {
|
||||
@@ -346,8 +345,7 @@ void NativePerformance::observe(
|
||||
return;
|
||||
}
|
||||
|
||||
auto durationThreshold =
|
||||
options.durationThreshold.value_or(HighResDuration::zero());
|
||||
auto durationThreshold = options.durationThreshold.value_or(0.0);
|
||||
|
||||
// observer of type multiple
|
||||
if (options.entryTypes.has_value()) {
|
||||
|
||||
+18
-18
@@ -32,7 +32,7 @@ using NativePerformancePerformanceObserverObserveOptions =
|
||||
// buffered
|
||||
std::optional<bool>,
|
||||
// durationThreshold
|
||||
std::optional<HighResDuration>>;
|
||||
std::optional<double>>;
|
||||
|
||||
template <>
|
||||
struct Bridging<PerformanceEntryType> {
|
||||
@@ -52,21 +52,21 @@ struct Bridging<PerformanceEntryType> {
|
||||
struct NativePerformanceEntry {
|
||||
std::string name;
|
||||
PerformanceEntryType entryType;
|
||||
HighResTimeStamp startTime;
|
||||
HighResDuration duration;
|
||||
DOMHighResTimeStamp startTime;
|
||||
DOMHighResTimeStamp duration;
|
||||
|
||||
// For PerformanceEventTiming only
|
||||
std::optional<HighResTimeStamp> processingStart;
|
||||
std::optional<HighResTimeStamp> processingEnd;
|
||||
std::optional<DOMHighResTimeStamp> processingStart;
|
||||
std::optional<DOMHighResTimeStamp> processingEnd;
|
||||
std::optional<PerformanceEntryInteractionId> interactionId;
|
||||
|
||||
// For PerformanceResourceTiming only
|
||||
std::optional<HighResTimeStamp> fetchStart;
|
||||
std::optional<HighResTimeStamp> requestStart;
|
||||
std::optional<HighResTimeStamp> connectStart;
|
||||
std::optional<HighResTimeStamp> connectEnd;
|
||||
std::optional<HighResTimeStamp> responseStart;
|
||||
std::optional<HighResTimeStamp> responseEnd;
|
||||
std::optional<DOMHighResTimeStamp> fetchStart;
|
||||
std::optional<DOMHighResTimeStamp> requestStart;
|
||||
std::optional<DOMHighResTimeStamp> connectStart;
|
||||
std::optional<DOMHighResTimeStamp> connectEnd;
|
||||
std::optional<DOMHighResTimeStamp> responseStart;
|
||||
std::optional<DOMHighResTimeStamp> responseEnd;
|
||||
std::optional<int> responseStatus;
|
||||
};
|
||||
|
||||
@@ -86,23 +86,23 @@ class NativePerformance : public NativePerformanceCxxSpec<NativePerformance> {
|
||||
#pragma mark - DOM Performance (High Resolution Time) (https://www.w3.org/TR/hr-time-3/#dom-performance)
|
||||
|
||||
// https://www.w3.org/TR/hr-time-3/#now-method
|
||||
HighResTimeStamp now(jsi::Runtime& rt);
|
||||
double now(jsi::Runtime& rt);
|
||||
|
||||
#pragma mark - User Timing Level 3 functions (https://w3c.github.io/user-timing/)
|
||||
|
||||
// https://w3c.github.io/user-timing/#mark-method
|
||||
HighResTimeStamp markWithResult(
|
||||
double markWithResult(
|
||||
jsi::Runtime& rt,
|
||||
std::string name,
|
||||
std::optional<HighResTimeStamp> startTime);
|
||||
std::optional<double> startTime);
|
||||
|
||||
// https://w3c.github.io/user-timing/#measure-method
|
||||
std::tuple<HighResTimeStamp, HighResDuration> measureWithResult(
|
||||
std::tuple<double, double> measureWithResult(
|
||||
jsi::Runtime& rt,
|
||||
std::string name,
|
||||
HighResTimeStamp startTime,
|
||||
HighResTimeStamp endTime,
|
||||
std::optional<HighResDuration> duration,
|
||||
double startTime,
|
||||
double endTime,
|
||||
std::optional<double> duration,
|
||||
std::optional<std::string> startMark,
|
||||
std::optional<std::string> endMark);
|
||||
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <react/timing/primitives.h>
|
||||
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <variant>
|
||||
@@ -29,8 +28,8 @@ enum class PerformanceEntryType {
|
||||
|
||||
struct AbstractPerformanceEntry {
|
||||
std::string name;
|
||||
HighResTimeStamp startTime;
|
||||
HighResDuration duration = HighResDuration::zero();
|
||||
DOMHighResTimeStamp startTime;
|
||||
DOMHighResTimeStamp duration = 0;
|
||||
};
|
||||
|
||||
struct PerformanceMark : AbstractPerformanceEntry {
|
||||
@@ -44,8 +43,8 @@ struct PerformanceMeasure : AbstractPerformanceEntry {
|
||||
|
||||
struct PerformanceEventTiming : AbstractPerformanceEntry {
|
||||
static constexpr PerformanceEntryType entryType = PerformanceEntryType::EVENT;
|
||||
HighResTimeStamp processingStart;
|
||||
HighResTimeStamp processingEnd;
|
||||
DOMHighResTimeStamp processingStart;
|
||||
DOMHighResTimeStamp processingEnd;
|
||||
PerformanceEntryInteractionId interactionId;
|
||||
};
|
||||
|
||||
@@ -58,13 +57,13 @@ struct PerformanceResourceTiming : AbstractPerformanceEntry {
|
||||
static constexpr PerformanceEntryType entryType =
|
||||
PerformanceEntryType::RESOURCE;
|
||||
/** Aligns with `startTime`. */
|
||||
HighResTimeStamp fetchStart;
|
||||
HighResTimeStamp requestStart;
|
||||
std::optional<HighResTimeStamp> connectStart;
|
||||
std::optional<HighResTimeStamp> connectEnd;
|
||||
std::optional<HighResTimeStamp> responseStart;
|
||||
DOMHighResTimeStamp fetchStart;
|
||||
DOMHighResTimeStamp requestStart;
|
||||
std::optional<DOMHighResTimeStamp> connectStart;
|
||||
std::optional<DOMHighResTimeStamp> connectEnd;
|
||||
std::optional<DOMHighResTimeStamp> responseStart;
|
||||
/** Aligns with `duration`. */
|
||||
std::optional<HighResTimeStamp> responseEnd;
|
||||
std::optional<DOMHighResTimeStamp> responseEnd;
|
||||
std::optional<int> responseStatus;
|
||||
};
|
||||
|
||||
|
||||
+2
-2
@@ -14,7 +14,7 @@ namespace facebook::react {
|
||||
|
||||
// Default duration threshold for reporting performance entries (0 means "report
|
||||
// all")
|
||||
constexpr HighResDuration DEFAULT_DURATION_THRESHOLD = HighResDuration::zero();
|
||||
constexpr double DEFAULT_DURATION_THRESHOLD = 0.0;
|
||||
|
||||
/**
|
||||
* Abstract performance entry buffer with reporting flags.
|
||||
@@ -22,7 +22,7 @@ constexpr HighResDuration DEFAULT_DURATION_THRESHOLD = HighResDuration::zero();
|
||||
*/
|
||||
class PerformanceEntryBuffer {
|
||||
public:
|
||||
HighResDuration durationThreshold = DEFAULT_DURATION_THRESHOLD;
|
||||
double durationThreshold{DEFAULT_DURATION_THRESHOLD};
|
||||
size_t droppedEntriesCount{0};
|
||||
|
||||
explicit PerformanceEntryBuffer() = default;
|
||||
|
||||
+30
-21
@@ -37,6 +37,10 @@ std::vector<PerformanceEntryType> getSupportedEntryTypesInternal() {
|
||||
return supportedEntryTypes;
|
||||
}
|
||||
|
||||
double performanceNow() {
|
||||
return chronoToDOMHighResTimeStamp(std::chrono::steady_clock::now());
|
||||
}
|
||||
|
||||
#if defined(__clang__)
|
||||
#define NO_DESTROY [[clang::no_destroy]]
|
||||
#else
|
||||
@@ -79,9 +83,9 @@ PerformanceEntryReporter::PerformanceEntryReporter()
|
||||
#endif
|
||||
}
|
||||
|
||||
HighResTimeStamp PerformanceEntryReporter::getCurrentTimeStamp() const {
|
||||
DOMHighResTimeStamp PerformanceEntryReporter::getCurrentTimeStamp() const {
|
||||
return timeStampProvider_ != nullptr ? timeStampProvider_()
|
||||
: HighResTimeStamp::now();
|
||||
: performanceNow();
|
||||
}
|
||||
|
||||
std::vector<PerformanceEntryType>
|
||||
@@ -169,7 +173,7 @@ void PerformanceEntryReporter::clearEntries(
|
||||
|
||||
PerformanceMark PerformanceEntryReporter::reportMark(
|
||||
const std::string& name,
|
||||
const std::optional<HighResTimeStamp>& startTime) {
|
||||
const std::optional<DOMHighResTimeStamp>& startTime) {
|
||||
// Resolve timings
|
||||
auto startTimeVal = startTime ? *startTime : getCurrentTimeStamp();
|
||||
const auto entry = PerformanceMark{{.name = name, .startTime = startTimeVal}};
|
||||
@@ -189,11 +193,11 @@ PerformanceMark PerformanceEntryReporter::reportMark(
|
||||
|
||||
PerformanceMeasure PerformanceEntryReporter::reportMeasure(
|
||||
const std::string& name,
|
||||
HighResTimeStamp startTime,
|
||||
HighResTimeStamp endTime,
|
||||
DOMHighResTimeStamp startTime,
|
||||
DOMHighResTimeStamp endTime,
|
||||
const std::optional<jsinspector_modern::DevToolsTrackEntryPayload>&
|
||||
trackMetadata) {
|
||||
HighResDuration duration = endTime - startTime;
|
||||
DOMHighResTimeStamp duration = endTime - startTime;
|
||||
|
||||
const auto entry = PerformanceMeasure{
|
||||
{.name = std::string(name),
|
||||
@@ -213,7 +217,7 @@ PerformanceMeasure PerformanceEntryReporter::reportMeasure(
|
||||
return entry;
|
||||
}
|
||||
|
||||
std::optional<HighResTimeStamp> PerformanceEntryReporter::getMarkTime(
|
||||
std::optional<DOMHighResTimeStamp> PerformanceEntryReporter::getMarkTime(
|
||||
const std::string& markName) const {
|
||||
std::shared_lock lock(buffersMutex_);
|
||||
|
||||
@@ -227,10 +231,10 @@ std::optional<HighResTimeStamp> PerformanceEntryReporter::getMarkTime(
|
||||
|
||||
void PerformanceEntryReporter::reportEvent(
|
||||
std::string name,
|
||||
HighResTimeStamp startTime,
|
||||
HighResDuration duration,
|
||||
HighResTimeStamp processingStart,
|
||||
HighResTimeStamp processingEnd,
|
||||
DOMHighResTimeStamp startTime,
|
||||
DOMHighResTimeStamp duration,
|
||||
DOMHighResTimeStamp processingStart,
|
||||
DOMHighResTimeStamp processingEnd,
|
||||
uint32_t interactionId) {
|
||||
eventCounts_[name]++;
|
||||
|
||||
@@ -256,8 +260,8 @@ void PerformanceEntryReporter::reportEvent(
|
||||
}
|
||||
|
||||
void PerformanceEntryReporter::reportLongTask(
|
||||
HighResTimeStamp startTime,
|
||||
HighResDuration duration) {
|
||||
DOMHighResTimeStamp startTime,
|
||||
DOMHighResTimeStamp duration) {
|
||||
const auto entry = PerformanceLongTaskTiming{
|
||||
{.name = std::string{"self"},
|
||||
.startTime = startTime,
|
||||
@@ -273,12 +277,12 @@ void PerformanceEntryReporter::reportLongTask(
|
||||
|
||||
PerformanceResourceTiming PerformanceEntryReporter::reportResourceTiming(
|
||||
const std::string& url,
|
||||
HighResTimeStamp fetchStart,
|
||||
HighResTimeStamp requestStart,
|
||||
std::optional<HighResTimeStamp> connectStart,
|
||||
std::optional<HighResTimeStamp> connectEnd,
|
||||
HighResTimeStamp responseStart,
|
||||
HighResTimeStamp responseEnd,
|
||||
DOMHighResTimeStamp fetchStart,
|
||||
DOMHighResTimeStamp requestStart,
|
||||
std::optional<DOMHighResTimeStamp> connectStart,
|
||||
std::optional<DOMHighResTimeStamp> connectEnd,
|
||||
DOMHighResTimeStamp responseStart,
|
||||
DOMHighResTimeStamp responseEnd,
|
||||
const std::optional<int>& responseStatus) {
|
||||
const auto entry = PerformanceResourceTiming{
|
||||
{.name = url, .startTime = fetchStart},
|
||||
@@ -309,7 +313,9 @@ void PerformanceEntryReporter::traceMark(const PerformanceMark& entry) const {
|
||||
auto [trackName, eventName] = parseTrackName(entry.name);
|
||||
|
||||
if (performanceTracer.isTracing()) {
|
||||
performanceTracer.reportMark(entry.name, entry.startTime);
|
||||
performanceTracer.reportMark(
|
||||
entry.name,
|
||||
HighResTimeStamp::fromDOMHighResTimeStamp(entry.startTime));
|
||||
}
|
||||
|
||||
if (ReactPerfettoLogger::isTracing()) {
|
||||
@@ -333,7 +339,10 @@ void PerformanceEntryReporter::traceMeasure(
|
||||
trackMetadata = {.track = trackName.value()};
|
||||
}
|
||||
performanceTracer.reportMeasure(
|
||||
eventName, entry.startTime, entry.duration, trackMetadata);
|
||||
eventName,
|
||||
HighResTimeStamp::fromDOMHighResTimeStamp(entry.startTime),
|
||||
HighResDuration::fromDOMHighResTimeStamp(entry.duration),
|
||||
trackMetadata);
|
||||
}
|
||||
|
||||
if (ReactPerfettoLogger::isTracing()) {
|
||||
|
||||
+19
-21
@@ -27,8 +27,7 @@ constexpr size_t EVENT_BUFFER_SIZE = 150;
|
||||
constexpr size_t LONG_TASK_BUFFER_SIZE = 200;
|
||||
constexpr size_t RESOURCE_TIMING_BUFFER_SIZE = 250;
|
||||
|
||||
constexpr HighResDuration LONG_TASK_DURATION_THRESHOLD =
|
||||
HighResDuration::fromMilliseconds(50);
|
||||
constexpr DOMHighResTimeStamp LONG_TASK_DURATION_THRESHOLD_MS = 50.0;
|
||||
|
||||
class PerformanceEntryReporter {
|
||||
public:
|
||||
@@ -67,9 +66,9 @@ class PerformanceEntryReporter {
|
||||
PerformanceEntryType entryType,
|
||||
const std::string& entryName);
|
||||
|
||||
HighResTimeStamp getCurrentTimeStamp() const;
|
||||
DOMHighResTimeStamp getCurrentTimeStamp() const;
|
||||
|
||||
void setTimeStampProvider(std::function<HighResTimeStamp()> provider) {
|
||||
void setTimeStampProvider(std::function<DOMHighResTimeStamp()> provider) {
|
||||
timeStampProvider_ = std::move(provider);
|
||||
}
|
||||
|
||||
@@ -81,38 +80,37 @@ class PerformanceEntryReporter {
|
||||
return eventCounts_;
|
||||
}
|
||||
|
||||
std::optional<HighResTimeStamp> getMarkTime(
|
||||
const std::string& markName) const;
|
||||
std::optional<double> getMarkTime(const std::string& markName) const;
|
||||
|
||||
PerformanceMark reportMark(
|
||||
const std::string& name,
|
||||
const std::optional<HighResTimeStamp>& startTime = std::nullopt);
|
||||
const std::optional<DOMHighResTimeStamp>& startTime = std::nullopt);
|
||||
|
||||
PerformanceMeasure reportMeasure(
|
||||
const std::string& name,
|
||||
HighResTimeStamp startTime,
|
||||
HighResTimeStamp endTime,
|
||||
double startTime,
|
||||
double endTime,
|
||||
const std::optional<jsinspector_modern::DevToolsTrackEntryPayload>&
|
||||
trackMetadata = std::nullopt);
|
||||
|
||||
void reportEvent(
|
||||
std::string name,
|
||||
HighResTimeStamp startTime,
|
||||
HighResDuration duration,
|
||||
HighResTimeStamp processingStart,
|
||||
HighResTimeStamp processingEnd,
|
||||
double startTime,
|
||||
double duration,
|
||||
double processingStart,
|
||||
double processingEnd,
|
||||
uint32_t interactionId);
|
||||
|
||||
void reportLongTask(HighResTimeStamp startTime, HighResDuration duration);
|
||||
void reportLongTask(double startTime, double duration);
|
||||
|
||||
PerformanceResourceTiming reportResourceTiming(
|
||||
const std::string& url,
|
||||
HighResTimeStamp fetchStart,
|
||||
HighResTimeStamp requestStart,
|
||||
std::optional<HighResTimeStamp> connectStart,
|
||||
std::optional<HighResTimeStamp> connectEnd,
|
||||
HighResTimeStamp responseStart,
|
||||
HighResTimeStamp responseEnd,
|
||||
DOMHighResTimeStamp fetchStart,
|
||||
DOMHighResTimeStamp requestStart,
|
||||
std::optional<DOMHighResTimeStamp> connectStart,
|
||||
std::optional<DOMHighResTimeStamp> connectEnd,
|
||||
DOMHighResTimeStamp responseStart,
|
||||
DOMHighResTimeStamp responseEnd,
|
||||
const std::optional<int>& responseStatus);
|
||||
|
||||
private:
|
||||
@@ -128,7 +126,7 @@ class PerformanceEntryReporter {
|
||||
|
||||
std::unordered_map<std::string, uint32_t> eventCounts_;
|
||||
|
||||
std::function<HighResTimeStamp()> timeStampProvider_ = nullptr;
|
||||
std::function<double()> timeStampProvider_ = nullptr;
|
||||
|
||||
const inline PerformanceEntryBuffer& getBuffer(
|
||||
PerformanceEntryType entryType) const {
|
||||
|
||||
@@ -7,15 +7,12 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "PerformanceEntryBuffer.h"
|
||||
#include "PerformanceObserverRegistry.h"
|
||||
|
||||
#include <react/timing/primitives.h>
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
#include "PerformanceEntryBuffer.h"
|
||||
#include "PerformanceObserverRegistry.h"
|
||||
|
||||
namespace facebook::react {
|
||||
|
||||
@@ -30,7 +27,7 @@ using PerformanceObserverCallback = std::function<void()>;
|
||||
* https://w3c.github.io/performance-timeline/#performanceobserverinit-dictionary
|
||||
*/
|
||||
struct PerformanceObserverObserveMultipleOptions {
|
||||
HighResDuration durationThreshold = DEFAULT_DURATION_THRESHOLD;
|
||||
double durationThreshold = 0.0;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -41,7 +38,7 @@ struct PerformanceObserverObserveMultipleOptions {
|
||||
*/
|
||||
struct PerformanceObserverObserveSingleOptions {
|
||||
bool buffered = false;
|
||||
HighResDuration durationThreshold = DEFAULT_DURATION_THRESHOLD;
|
||||
double durationThreshold = 0.0;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -127,7 +124,7 @@ class PerformanceObserver
|
||||
PerformanceObserverEntryTypeFilter observedTypes_;
|
||||
|
||||
/// https://www.w3.org/TR/event-timing/#sec-modifications-perf-timeline
|
||||
HighResDuration durationThreshold_ = DEFAULT_DURATION_THRESHOLD;
|
||||
double durationThreshold_{DEFAULT_DURATION_THRESHOLD};
|
||||
std::vector<PerformanceEntry> buffer_;
|
||||
bool didScheduleFlushBuffer_ = false;
|
||||
bool requiresDroppedEntries_ = false;
|
||||
|
||||
+60
-200
@@ -58,10 +58,8 @@ namespace facebook::react {
|
||||
[&](const auto& entryDetails) -> std::ostream& {
|
||||
os << "{ .name = \"" << entryDetails.name << "\"" << ", .entryType = "
|
||||
<< entryTypeNames[static_cast<int>(entryDetails.entryType) - 1]
|
||||
<< ", .startTime = "
|
||||
<< entryDetails.startTime.toDOMHighResTimeStamp()
|
||||
<< ", .duration = " << entryDetails.duration.toDOMHighResTimeStamp()
|
||||
<< " }";
|
||||
<< ", .startTime = " << entryDetails.startTime
|
||||
<< ", .duration = " << entryDetails.duration << " }";
|
||||
return os;
|
||||
},
|
||||
entry);
|
||||
@@ -79,116 +77,60 @@ std::vector<PerformanceEntry> toSorted(
|
||||
|
||||
TEST(PerformanceEntryReporter, PerformanceEntryReporterTestReportMarks) {
|
||||
auto reporter = PerformanceEntryReporter::getInstance();
|
||||
auto timeOrigin = HighResTimeStamp::now();
|
||||
|
||||
reporter->clearEntries();
|
||||
|
||||
reporter->reportMark("mark0", timeOrigin);
|
||||
reporter->reportMark(
|
||||
"mark1", timeOrigin + HighResDuration::fromMilliseconds(1));
|
||||
reporter->reportMark(
|
||||
"mark2", timeOrigin + HighResDuration::fromMilliseconds(2));
|
||||
reporter->reportMark("mark0", 0);
|
||||
reporter->reportMark("mark1", 1);
|
||||
reporter->reportMark("mark2", 2);
|
||||
// Report mark0 again
|
||||
reporter->reportMark(
|
||||
"mark0", timeOrigin + HighResDuration::fromMilliseconds(3));
|
||||
reporter->reportMark("mark0", 3);
|
||||
|
||||
const auto entries = toSorted(reporter->getEntries());
|
||||
|
||||
ASSERT_EQ(4, entries.size());
|
||||
|
||||
const std::vector<PerformanceEntry> expected = {
|
||||
PerformanceMark{
|
||||
{.name = "mark0",
|
||||
.startTime = timeOrigin,
|
||||
.duration = HighResDuration::zero()}},
|
||||
PerformanceMark{
|
||||
{.name = "mark1",
|
||||
.startTime = timeOrigin + HighResDuration::fromMilliseconds(1),
|
||||
.duration = HighResDuration::zero()}},
|
||||
PerformanceMark{
|
||||
{.name = "mark2",
|
||||
.startTime = timeOrigin + HighResDuration::fromMilliseconds(2),
|
||||
.duration = HighResDuration::zero()}},
|
||||
PerformanceMark{
|
||||
{.name = "mark0",
|
||||
.startTime = timeOrigin + HighResDuration::fromMilliseconds(3),
|
||||
.duration = HighResDuration::zero()}}};
|
||||
PerformanceMark{{.name = "mark0", .startTime = 0, .duration = 0}},
|
||||
PerformanceMark{{.name = "mark1", .startTime = 1, .duration = 0}},
|
||||
PerformanceMark{{.name = "mark2", .startTime = 2, .duration = 0}},
|
||||
PerformanceMark{{.name = "mark0", .startTime = 3, .duration = 0}}};
|
||||
|
||||
ASSERT_EQ(expected, entries);
|
||||
}
|
||||
|
||||
TEST(PerformanceEntryReporter, PerformanceEntryReporterTestReportMeasures) {
|
||||
auto reporter = PerformanceEntryReporter::getInstance();
|
||||
auto timeOrigin = HighResTimeStamp::now();
|
||||
reporter->clearEntries();
|
||||
|
||||
reporter->reportMark("mark0", timeOrigin);
|
||||
reporter->reportMark(
|
||||
"mark1", timeOrigin + HighResDuration::fromMilliseconds(1));
|
||||
reporter->reportMark(
|
||||
"mark2", timeOrigin + HighResDuration::fromMilliseconds(2));
|
||||
reporter->reportMark("mark0", 0);
|
||||
reporter->reportMark("mark1", 1);
|
||||
reporter->reportMark("mark2", 2);
|
||||
|
||||
reporter->reportMeasure(
|
||||
"measure0",
|
||||
timeOrigin,
|
||||
timeOrigin + HighResDuration::fromMilliseconds(2));
|
||||
reporter->reportMeasure(
|
||||
"measure1",
|
||||
timeOrigin,
|
||||
timeOrigin + HighResDuration::fromMilliseconds(3));
|
||||
reporter->reportMeasure("measure0", 0, 2);
|
||||
reporter->reportMeasure("measure1", 0, 3);
|
||||
|
||||
reporter->reportMark(
|
||||
"mark3", timeOrigin + HighResDuration::fromNanoseconds(2.5 * 1e6));
|
||||
reporter->reportMeasure(
|
||||
"measure2",
|
||||
timeOrigin + HighResDuration::fromMilliseconds(2),
|
||||
timeOrigin + HighResDuration::fromMilliseconds(2));
|
||||
reporter->reportMark(
|
||||
"mark4", timeOrigin + HighResDuration::fromMilliseconds(3));
|
||||
reporter->reportMark("mark3", 2.5);
|
||||
reporter->reportMeasure("measure2", 2.0, 2.0);
|
||||
reporter->reportMark("mark4", 3.0);
|
||||
|
||||
const auto entries = toSorted(reporter->getEntries());
|
||||
|
||||
const std::vector<PerformanceEntry> expected = {
|
||||
PerformanceMark{
|
||||
{.name = "mark0",
|
||||
.startTime = timeOrigin,
|
||||
.duration = HighResDuration::zero()}},
|
||||
PerformanceMeasure{
|
||||
{.name = "measure0",
|
||||
.startTime = timeOrigin,
|
||||
.duration = HighResDuration::fromMilliseconds(2)}},
|
||||
PerformanceMeasure{
|
||||
{.name = "measure1",
|
||||
.startTime = timeOrigin,
|
||||
.duration = HighResDuration::fromMilliseconds(3)}},
|
||||
PerformanceMark{
|
||||
{.name = "mark1",
|
||||
.startTime = timeOrigin + HighResDuration::fromMilliseconds(1),
|
||||
.duration = HighResDuration::zero()}},
|
||||
PerformanceMark{
|
||||
{.name = "mark2",
|
||||
.startTime = timeOrigin + HighResDuration::fromMilliseconds(2),
|
||||
.duration = HighResDuration::zero()}},
|
||||
PerformanceMeasure{
|
||||
{.name = "measure2",
|
||||
.startTime = timeOrigin + HighResDuration::fromMilliseconds(2),
|
||||
.duration = HighResDuration::zero()}},
|
||||
PerformanceMark{
|
||||
{.name = "mark3",
|
||||
.startTime =
|
||||
timeOrigin + HighResDuration::fromNanoseconds(2.5 * 1e6),
|
||||
.duration = HighResDuration::zero()}},
|
||||
PerformanceMark{
|
||||
{.name = "mark4",
|
||||
.startTime = timeOrigin + HighResDuration::fromMilliseconds(3),
|
||||
.duration = HighResDuration::zero()}}};
|
||||
PerformanceMark{{.name = "mark0", .startTime = 0, .duration = 0}},
|
||||
PerformanceMeasure{{.name = "measure0", .startTime = 0, .duration = 2}},
|
||||
PerformanceMeasure{{.name = "measure1", .startTime = 0, .duration = 3}},
|
||||
PerformanceMark{{.name = "mark1", .startTime = 1, .duration = 0}},
|
||||
PerformanceMark{{.name = "mark2", .startTime = 2, .duration = 0}},
|
||||
PerformanceMeasure{{.name = "measure2", .startTime = 2, .duration = 0}},
|
||||
PerformanceMark{{.name = "mark3", .startTime = 2.5, .duration = 0}},
|
||||
PerformanceMark{{.name = "mark4", .startTime = 3, .duration = 0}}};
|
||||
|
||||
ASSERT_EQ(expected, entries);
|
||||
}
|
||||
|
||||
TEST(PerformanceEntryReporter, PerformanceEntryReporterTestGetEntries) {
|
||||
auto reporter = PerformanceEntryReporter::getInstance();
|
||||
auto timeOrigin = HighResTimeStamp::now();
|
||||
reporter->clearEntries();
|
||||
|
||||
{
|
||||
@@ -196,61 +138,27 @@ TEST(PerformanceEntryReporter, PerformanceEntryReporterTestGetEntries) {
|
||||
ASSERT_EQ(0, entries.size());
|
||||
}
|
||||
|
||||
reporter->reportMark("common_name", timeOrigin);
|
||||
reporter->reportMark(
|
||||
"mark1", timeOrigin + HighResDuration::fromMilliseconds(1));
|
||||
reporter->reportMark(
|
||||
"mark2", timeOrigin + HighResDuration::fromMilliseconds(2));
|
||||
reporter->reportMark("common_name", 0);
|
||||
reporter->reportMark("mark1", 1);
|
||||
reporter->reportMark("mark2", 2);
|
||||
|
||||
reporter->reportMeasure(
|
||||
"common_name",
|
||||
timeOrigin,
|
||||
timeOrigin + HighResDuration::fromMilliseconds(2));
|
||||
reporter->reportMeasure(
|
||||
"measure1",
|
||||
timeOrigin,
|
||||
timeOrigin + HighResDuration::fromMilliseconds(3));
|
||||
reporter->reportMeasure(
|
||||
"measure2",
|
||||
timeOrigin + HighResDuration::fromMilliseconds(1),
|
||||
timeOrigin + HighResDuration::fromMilliseconds(6));
|
||||
reporter->reportMeasure(
|
||||
"measure3",
|
||||
timeOrigin + HighResDuration::fromNanoseconds(1.5 * 1e6),
|
||||
timeOrigin + HighResDuration::fromMilliseconds(2));
|
||||
reporter->reportMeasure("common_name", 0, 2);
|
||||
reporter->reportMeasure("measure1", 0, 3);
|
||||
reporter->reportMeasure("measure2", 1, 6);
|
||||
reporter->reportMeasure("measure3", 1.5, 2);
|
||||
|
||||
{
|
||||
const auto allEntries = toSorted(reporter->getEntries());
|
||||
const std::vector<PerformanceEntry> expected = {
|
||||
PerformanceMark{
|
||||
{.name = "common_name",
|
||||
.startTime = timeOrigin,
|
||||
.duration = HighResDuration::zero()}},
|
||||
PerformanceMark{{.name = "common_name", .startTime = 0, .duration = 0}},
|
||||
PerformanceMeasure{
|
||||
{.name = "common_name",
|
||||
.startTime = timeOrigin,
|
||||
.duration = HighResDuration::fromMilliseconds(2)}},
|
||||
{.name = "common_name", .startTime = 0, .duration = 2}},
|
||||
PerformanceMeasure{{.name = "measure1", .startTime = 0, .duration = 3}},
|
||||
PerformanceMark{{.name = "mark1", .startTime = 1, .duration = 0}},
|
||||
PerformanceMeasure{{.name = "measure2", .startTime = 1, .duration = 5}},
|
||||
PerformanceMeasure{
|
||||
{.name = "measure1",
|
||||
.startTime = timeOrigin,
|
||||
.duration = HighResDuration::fromMilliseconds(3)}},
|
||||
PerformanceMark{
|
||||
{.name = "mark1",
|
||||
.startTime = timeOrigin + HighResDuration::fromMilliseconds(1),
|
||||
.duration = HighResDuration::zero()}},
|
||||
PerformanceMeasure{
|
||||
{.name = "measure2",
|
||||
.startTime = timeOrigin + HighResDuration::fromMilliseconds(1),
|
||||
.duration = HighResDuration::fromMilliseconds(5)}},
|
||||
PerformanceMeasure{
|
||||
{.name = "measure3",
|
||||
.startTime =
|
||||
timeOrigin + HighResDuration::fromNanoseconds(1.5 * 1e6),
|
||||
.duration = HighResDuration::fromNanoseconds(0.5 * 1e6)}},
|
||||
PerformanceMark{
|
||||
{.name = "mark2",
|
||||
.startTime = timeOrigin + HighResDuration::fromMilliseconds(2),
|
||||
.duration = HighResDuration::zero()}}};
|
||||
{.name = "measure3", .startTime = 1.5, .duration = 0.5}},
|
||||
PerformanceMark{{.name = "mark2", .startTime = 2, .duration = 0}}};
|
||||
ASSERT_EQ(expected, allEntries);
|
||||
}
|
||||
|
||||
@@ -258,18 +166,9 @@ TEST(PerformanceEntryReporter, PerformanceEntryReporterTestGetEntries) {
|
||||
const auto marks =
|
||||
toSorted(reporter->getEntries(PerformanceEntryType::MARK));
|
||||
const std::vector<PerformanceEntry> expected = {
|
||||
PerformanceMark{
|
||||
{.name = "common_name",
|
||||
.startTime = timeOrigin,
|
||||
.duration = HighResDuration::zero()}},
|
||||
PerformanceMark{
|
||||
{.name = "mark1",
|
||||
.startTime = timeOrigin + HighResDuration::fromMilliseconds(1),
|
||||
.duration = HighResDuration::zero()}},
|
||||
PerformanceMark{
|
||||
{.name = "mark2",
|
||||
.startTime = timeOrigin + HighResDuration::fromMilliseconds(2),
|
||||
.duration = HighResDuration::zero()}}};
|
||||
PerformanceMark{{.name = "common_name", .startTime = 0, .duration = 0}},
|
||||
PerformanceMark{{.name = "mark1", .startTime = 1, .duration = 0}},
|
||||
PerformanceMark{{.name = "mark2", .startTime = 2, .duration = 0}}};
|
||||
ASSERT_EQ(expected, marks);
|
||||
}
|
||||
|
||||
@@ -278,28 +177,17 @@ TEST(PerformanceEntryReporter, PerformanceEntryReporterTestGetEntries) {
|
||||
toSorted(reporter->getEntries(PerformanceEntryType::MEASURE));
|
||||
const std::vector<PerformanceEntry> expected = {
|
||||
PerformanceMeasure{
|
||||
{.name = "common_name",
|
||||
.startTime = timeOrigin,
|
||||
.duration = HighResDuration::fromMilliseconds(2)}},
|
||||
{.name = "common_name", .startTime = 0, .duration = 2}},
|
||||
PerformanceMeasure{{.name = "measure1", .startTime = 0, .duration = 3}},
|
||||
PerformanceMeasure{{.name = "measure2", .startTime = 1, .duration = 5}},
|
||||
PerformanceMeasure{
|
||||
{.name = "measure1",
|
||||
.startTime = timeOrigin,
|
||||
.duration = HighResDuration::fromMilliseconds(3)}},
|
||||
PerformanceMeasure{
|
||||
{.name = "measure2",
|
||||
.startTime = timeOrigin + HighResDuration::fromMilliseconds(1),
|
||||
.duration = HighResDuration::fromMilliseconds(5)}},
|
||||
PerformanceMeasure{
|
||||
{.name = "measure3",
|
||||
.startTime =
|
||||
timeOrigin + HighResDuration::fromNanoseconds(1.5 * 1e6),
|
||||
.duration = HighResDuration::fromNanoseconds(0.5 * 1e6)}}};
|
||||
{.name = "measure3", .startTime = 1.5, .duration = 0.5}}};
|
||||
ASSERT_EQ(expected, measures);
|
||||
}
|
||||
|
||||
{
|
||||
const std::vector<PerformanceEntry> expected = {
|
||||
PerformanceMark{{.name = "common_name", .startTime = timeOrigin}}};
|
||||
PerformanceMark{{.name = "common_name", .startTime = 0}}};
|
||||
const auto commonName =
|
||||
reporter->getEntries(PerformanceEntryType::MARK, "common_name");
|
||||
ASSERT_EQ(expected, commonName);
|
||||
@@ -307,9 +195,7 @@ TEST(PerformanceEntryReporter, PerformanceEntryReporterTestGetEntries) {
|
||||
|
||||
{
|
||||
const std::vector<PerformanceEntry> expected = {PerformanceMeasure{
|
||||
{.name = "common_name",
|
||||
.startTime = timeOrigin,
|
||||
.duration = HighResDuration::fromMilliseconds(2)}}};
|
||||
{.name = "common_name", .startTime = 0, .duration = 2}}};
|
||||
const auto commonName =
|
||||
reporter->getEntries(PerformanceEntryType::MEASURE, "common_name");
|
||||
ASSERT_EQ(expected, commonName);
|
||||
@@ -318,52 +204,26 @@ TEST(PerformanceEntryReporter, PerformanceEntryReporterTestGetEntries) {
|
||||
|
||||
TEST(PerformanceEntryReporter, PerformanceEntryReporterTestClearMarks) {
|
||||
auto reporter = PerformanceEntryReporter::getInstance();
|
||||
auto timeOrigin = HighResTimeStamp::now();
|
||||
reporter->clearEntries();
|
||||
|
||||
reporter->reportMark("common_name", timeOrigin);
|
||||
reporter->reportMark(
|
||||
"mark1", timeOrigin + HighResDuration::fromMilliseconds(1));
|
||||
reporter->reportMark(
|
||||
"mark1", timeOrigin + HighResDuration::fromNanoseconds(2.1 * 1e6));
|
||||
reporter->reportMark(
|
||||
"mark2", timeOrigin + HighResDuration::fromMilliseconds(2));
|
||||
reporter->reportMark("common_name", 0);
|
||||
reporter->reportMark("mark1", 1);
|
||||
reporter->reportMark("mark1", 2.1);
|
||||
reporter->reportMark("mark2", 2);
|
||||
|
||||
reporter->reportMeasure(
|
||||
"common_name",
|
||||
timeOrigin,
|
||||
timeOrigin + HighResDuration::fromMilliseconds(2));
|
||||
reporter->reportMeasure(
|
||||
"measure1",
|
||||
timeOrigin,
|
||||
timeOrigin + HighResDuration::fromMilliseconds(3));
|
||||
reporter->reportMeasure(
|
||||
"measure2",
|
||||
timeOrigin + HighResDuration::fromMilliseconds(1),
|
||||
timeOrigin + HighResDuration::fromMilliseconds(6));
|
||||
reporter->reportMeasure(
|
||||
"measure3",
|
||||
timeOrigin + HighResDuration::fromNanoseconds(1.5 * 1e6),
|
||||
timeOrigin + HighResDuration::fromMilliseconds(2));
|
||||
reporter->reportMeasure("common_name", 0, 2);
|
||||
reporter->reportMeasure("measure1", 0, 3);
|
||||
reporter->reportMeasure("measure2", 1, 6);
|
||||
reporter->reportMeasure("measure3", 1.5, 2);
|
||||
|
||||
reporter->clearEntries(PerformanceEntryType::MARK, "common_name");
|
||||
|
||||
{
|
||||
auto entries = toSorted(reporter->getEntries(PerformanceEntryType::MARK));
|
||||
std::vector<PerformanceEntry> expected = {
|
||||
PerformanceMark{
|
||||
{.name = "mark1",
|
||||
.startTime = timeOrigin + HighResDuration::fromMilliseconds(1),
|
||||
.duration = HighResDuration::zero()}},
|
||||
PerformanceMark{
|
||||
{.name = "mark2",
|
||||
.startTime = timeOrigin + HighResDuration::fromMilliseconds(2),
|
||||
.duration = HighResDuration::zero()}},
|
||||
PerformanceMark{
|
||||
{.name = "mark1",
|
||||
.startTime =
|
||||
timeOrigin + HighResDuration::fromNanoseconds(2.1 * 1e6),
|
||||
.duration = HighResDuration::zero()}},
|
||||
PerformanceMark{{.name = "mark1", .startTime = 1, .duration = 0}},
|
||||
PerformanceMark{{.name = "mark2", .startTime = 2, .duration = 0}},
|
||||
PerformanceMark{{.name = "mark1", .startTime = 2.1, .duration = 0}},
|
||||
};
|
||||
ASSERT_EQ(expected, entries);
|
||||
}
|
||||
|
||||
+43
-237
@@ -49,14 +49,12 @@ TEST(PerformanceObserver, PerformanceObserverTestObserveFlushes) {
|
||||
bool callbackCalled = false;
|
||||
auto observer = PerformanceObserver::create(
|
||||
reporter->getObserverRegistry(), [&]() { callbackCalled = true; });
|
||||
auto timeOrigin = HighResTimeStamp::now();
|
||||
observer->observe(PerformanceEntryType::MARK);
|
||||
|
||||
// buffer is empty
|
||||
ASSERT_FALSE(callbackCalled);
|
||||
|
||||
reporter->reportMark(
|
||||
"test", timeOrigin + HighResDuration::fromMilliseconds(10));
|
||||
reporter->reportMark("test", 10);
|
||||
ASSERT_TRUE(callbackCalled);
|
||||
|
||||
observer->disconnect();
|
||||
@@ -66,12 +64,10 @@ TEST(PerformanceObserver, PerformanceObserverTestFilteredSingle) {
|
||||
auto reporter = PerformanceEntryReporter::getInstance();
|
||||
reporter->clearEntries();
|
||||
|
||||
auto timeOrigin = HighResTimeStamp::now();
|
||||
auto observer =
|
||||
PerformanceObserver::create(reporter->getObserverRegistry(), [&]() {});
|
||||
observer->observe(PerformanceEntryType::MEASURE);
|
||||
reporter->reportMark(
|
||||
"test", timeOrigin + HighResDuration::fromMilliseconds(10));
|
||||
reporter->reportMark("test", 10);
|
||||
|
||||
// wrong type
|
||||
ASSERT_EQ(observer->takeRecords().size(), 0);
|
||||
@@ -83,34 +79,15 @@ TEST(PerformanceObserver, PerformanceObserverTestFilterMulti) {
|
||||
auto reporter = PerformanceEntryReporter::getInstance();
|
||||
reporter->clearEntries();
|
||||
|
||||
auto timeOrigin = HighResTimeStamp::now();
|
||||
auto callbackCalled = false;
|
||||
auto observer = PerformanceObserver::create(
|
||||
reporter->getObserverRegistry(), [&]() { callbackCalled = true; });
|
||||
observer->observe(
|
||||
{PerformanceEntryType::MEASURE, PerformanceEntryType::MARK});
|
||||
|
||||
reporter->reportEvent(
|
||||
"test1",
|
||||
timeOrigin + HighResDuration::fromMilliseconds(10),
|
||||
HighResDuration::fromMilliseconds(10),
|
||||
timeOrigin,
|
||||
timeOrigin,
|
||||
0);
|
||||
reporter->reportEvent(
|
||||
"test2",
|
||||
timeOrigin + HighResDuration::fromMilliseconds(10),
|
||||
HighResDuration::fromMilliseconds(10),
|
||||
timeOrigin,
|
||||
timeOrigin,
|
||||
0);
|
||||
reporter->reportEvent(
|
||||
"test3",
|
||||
timeOrigin + HighResDuration::fromMilliseconds(10),
|
||||
HighResDuration::fromMilliseconds(10),
|
||||
timeOrigin,
|
||||
timeOrigin,
|
||||
0);
|
||||
reporter->reportEvent("test1", 10, 10, 0, 0, 0);
|
||||
reporter->reportEvent("test2", 10, 10, 0, 0, 0);
|
||||
reporter->reportEvent("test3", 10, 10, 0, 0, 0);
|
||||
|
||||
ASSERT_EQ(observer->takeRecords().size(), 0);
|
||||
ASSERT_FALSE(callbackCalled);
|
||||
@@ -124,14 +101,11 @@ TEST(
|
||||
auto reporter = PerformanceEntryReporter::getInstance();
|
||||
reporter->clearEntries();
|
||||
|
||||
auto timeOrigin = HighResTimeStamp::now();
|
||||
auto callbackCalled = false;
|
||||
auto observer = PerformanceObserver::create(
|
||||
reporter->getObserverRegistry(), [&]() { callbackCalled = true; });
|
||||
observer->observe(PerformanceEntryType::MEASURE);
|
||||
|
||||
reporter->reportMark(
|
||||
"test", timeOrigin + HighResDuration::fromMilliseconds(10));
|
||||
reporter->reportMark("test", 10);
|
||||
|
||||
ASSERT_FALSE(callbackCalled);
|
||||
|
||||
@@ -142,34 +116,14 @@ TEST(PerformanceObserver, PerformanceObserverTestFilterMultiCallbackNotCalled) {
|
||||
auto reporter = PerformanceEntryReporter::getInstance();
|
||||
reporter->clearEntries();
|
||||
|
||||
auto timeOrigin = HighResTimeStamp::now();
|
||||
auto callbackCalled = false;
|
||||
auto observer = PerformanceObserver::create(
|
||||
reporter->getObserverRegistry(), [&]() { callbackCalled = true; });
|
||||
observer->observe(
|
||||
{PerformanceEntryType::MEASURE, PerformanceEntryType::MARK});
|
||||
|
||||
reporter->reportEvent(
|
||||
"test1",
|
||||
timeOrigin + HighResDuration::fromMilliseconds(10),
|
||||
HighResDuration::fromMilliseconds(10),
|
||||
timeOrigin,
|
||||
timeOrigin,
|
||||
0);
|
||||
reporter->reportEvent(
|
||||
"test2",
|
||||
timeOrigin + HighResDuration::fromMilliseconds(10),
|
||||
HighResDuration::fromMilliseconds(10),
|
||||
timeOrigin,
|
||||
timeOrigin,
|
||||
0);
|
||||
reporter->reportEvent(
|
||||
"off3",
|
||||
timeOrigin + HighResDuration::fromMilliseconds(10),
|
||||
HighResDuration::fromMilliseconds(10),
|
||||
timeOrigin,
|
||||
timeOrigin,
|
||||
0);
|
||||
reporter->reportEvent("test1", 10, 10, 0, 0, 0);
|
||||
reporter->reportEvent("test2", 10, 10, 0, 0, 0);
|
||||
reporter->reportEvent("off3", 10, 10, 0, 0, 0);
|
||||
|
||||
ASSERT_FALSE(callbackCalled);
|
||||
|
||||
@@ -180,32 +134,18 @@ TEST(PerformanceObserver, PerformanceObserverTestObserveTakeRecords) {
|
||||
auto reporter = PerformanceEntryReporter::getInstance();
|
||||
reporter->clearEntries();
|
||||
|
||||
auto timeOrigin = HighResTimeStamp::now();
|
||||
auto observer =
|
||||
PerformanceObserver::create(reporter->getObserverRegistry(), [&]() {});
|
||||
observer->observe(PerformanceEntryType::MARK);
|
||||
|
||||
reporter->reportMark(
|
||||
"test1", timeOrigin + HighResDuration::fromMilliseconds(10));
|
||||
reporter->reportMeasure(
|
||||
"off",
|
||||
timeOrigin + HighResDuration::fromMilliseconds(10),
|
||||
timeOrigin + HighResDuration::fromMilliseconds(20));
|
||||
reporter->reportMark(
|
||||
"test2", timeOrigin + HighResDuration::fromMilliseconds(20));
|
||||
reporter->reportMark(
|
||||
"test3", timeOrigin + HighResDuration::fromMilliseconds(30));
|
||||
reporter->reportMark("test1", 10);
|
||||
reporter->reportMeasure("off", 10, 20);
|
||||
reporter->reportMark("test2", 20);
|
||||
reporter->reportMark("test3", 30);
|
||||
|
||||
const std::vector<PerformanceEntry> expected = {
|
||||
PerformanceMark{
|
||||
{.name = "test1",
|
||||
.startTime = timeOrigin + HighResDuration::fromMilliseconds(10)}},
|
||||
PerformanceMark{
|
||||
{.name = "test2",
|
||||
.startTime = timeOrigin + HighResDuration::fromMilliseconds(20)}},
|
||||
PerformanceMark{
|
||||
{.name = "test3",
|
||||
.startTime = timeOrigin + HighResDuration::fromMilliseconds(30)}},
|
||||
PerformanceMark{{.name = "test1", .startTime = 10}},
|
||||
PerformanceMark{{.name = "test2", .startTime = 20}},
|
||||
PerformanceMark{{.name = "test3", .startTime = 30}},
|
||||
};
|
||||
|
||||
ASSERT_EQ(expected, observer->takeRecords());
|
||||
@@ -217,66 +157,19 @@ TEST(PerformanceObserver, PerformanceObserverTestObserveDurationThreshold) {
|
||||
auto reporter = PerformanceEntryReporter::getInstance();
|
||||
reporter->clearEntries();
|
||||
|
||||
auto timeOrigin = HighResTimeStamp::now();
|
||||
auto observer =
|
||||
PerformanceObserver::create(reporter->getObserverRegistry(), [&]() {});
|
||||
observer->observe(
|
||||
PerformanceEntryType::EVENT,
|
||||
{.durationThreshold = HighResDuration::fromMilliseconds(50)});
|
||||
|
||||
reporter->reportEvent(
|
||||
"test1",
|
||||
timeOrigin,
|
||||
HighResDuration::fromMilliseconds(50),
|
||||
timeOrigin,
|
||||
timeOrigin,
|
||||
0);
|
||||
reporter->reportEvent(
|
||||
"test2",
|
||||
timeOrigin,
|
||||
HighResDuration::fromMilliseconds(100),
|
||||
timeOrigin,
|
||||
timeOrigin,
|
||||
0);
|
||||
reporter->reportEvent(
|
||||
"off1",
|
||||
timeOrigin,
|
||||
HighResDuration::fromMilliseconds(40),
|
||||
timeOrigin,
|
||||
timeOrigin,
|
||||
0);
|
||||
reporter->reportMark(
|
||||
"off2", timeOrigin + HighResDuration::fromMilliseconds(100));
|
||||
reporter->reportEvent(
|
||||
"test3",
|
||||
timeOrigin,
|
||||
HighResDuration::fromMilliseconds(60),
|
||||
timeOrigin,
|
||||
timeOrigin,
|
||||
0);
|
||||
observer->observe(PerformanceEntryType::EVENT, {.durationThreshold = 50});
|
||||
reporter->reportEvent("test1", 0, 50, 0, 0, 0);
|
||||
reporter->reportEvent("test2", 0, 100, 0, 0, 0);
|
||||
reporter->reportEvent("off1", 0, 40, 0, 0, 0);
|
||||
reporter->reportMark("off2", 100);
|
||||
reporter->reportEvent("test3", 0, 60, 0, 0, 0);
|
||||
|
||||
const std::vector<PerformanceEntry> expected = {
|
||||
PerformanceEventTiming{
|
||||
{.name = "test1",
|
||||
.startTime = timeOrigin,
|
||||
.duration = HighResDuration::fromMilliseconds(50)},
|
||||
timeOrigin,
|
||||
timeOrigin,
|
||||
0},
|
||||
PerformanceEventTiming{
|
||||
{.name = "test2",
|
||||
.startTime = timeOrigin,
|
||||
.duration = HighResDuration::fromMilliseconds(100)},
|
||||
timeOrigin,
|
||||
timeOrigin,
|
||||
0},
|
||||
PerformanceEventTiming{
|
||||
{.name = "test3",
|
||||
.startTime = timeOrigin,
|
||||
.duration = HighResDuration::fromMilliseconds(60)},
|
||||
timeOrigin,
|
||||
timeOrigin,
|
||||
0},
|
||||
PerformanceEventTiming{{.name = "test1", .duration = 50}, 0, 0, 0},
|
||||
PerformanceEventTiming{{.name = "test2", .duration = 100}, 0, 0, 0},
|
||||
PerformanceEventTiming{{.name = "test3", .duration = 60}, 0, 0, 0},
|
||||
};
|
||||
|
||||
ASSERT_EQ(expected, observer->takeRecords());
|
||||
@@ -288,65 +181,23 @@ TEST(PerformanceObserver, PerformanceObserverTestObserveBuffered) {
|
||||
auto reporter = PerformanceEntryReporter::getInstance();
|
||||
reporter->clearEntries();
|
||||
|
||||
auto timeOrigin = HighResTimeStamp::now();
|
||||
reporter->reportEvent(
|
||||
"test1",
|
||||
timeOrigin,
|
||||
HighResDuration::fromMilliseconds(50),
|
||||
timeOrigin,
|
||||
timeOrigin,
|
||||
0);
|
||||
reporter->reportEvent(
|
||||
"test2",
|
||||
timeOrigin,
|
||||
HighResDuration::fromMilliseconds(100),
|
||||
timeOrigin,
|
||||
timeOrigin,
|
||||
0);
|
||||
reporter->reportEvent(
|
||||
"test3",
|
||||
timeOrigin,
|
||||
HighResDuration::fromMilliseconds(40),
|
||||
timeOrigin,
|
||||
timeOrigin,
|
||||
0);
|
||||
reporter->reportEvent(
|
||||
"test4",
|
||||
timeOrigin,
|
||||
HighResDuration::fromMilliseconds(100),
|
||||
timeOrigin,
|
||||
timeOrigin,
|
||||
0);
|
||||
reporter->reportEvent("test1", 0, 50, 0, 0, 0);
|
||||
reporter->reportEvent("test2", 0, 100, 0, 0, 0);
|
||||
reporter->reportEvent("test3", 0, 40, 0, 0, 0);
|
||||
reporter->reportEvent("test4", 0, 100, 0, 0, 0);
|
||||
|
||||
auto observer =
|
||||
PerformanceObserver::create(reporter->getObserverRegistry(), [&]() {});
|
||||
observer->observe(
|
||||
PerformanceEntryType::EVENT,
|
||||
{.buffered = true,
|
||||
.durationThreshold = HighResDuration::fromMilliseconds(50)});
|
||||
PerformanceEntryType::EVENT, {.buffered = true, .durationThreshold = 50});
|
||||
|
||||
const std::vector<PerformanceEntry> expected = {
|
||||
PerformanceEventTiming{
|
||||
{.name = "test1",
|
||||
.startTime = timeOrigin,
|
||||
.duration = HighResDuration::fromMilliseconds(50)},
|
||||
timeOrigin,
|
||||
timeOrigin,
|
||||
0},
|
||||
{.name = "test1", .startTime = 0, .duration = 50}, 0, 0, 0},
|
||||
PerformanceEventTiming{
|
||||
{.name = "test2",
|
||||
.startTime = timeOrigin,
|
||||
.duration = HighResDuration::fromMilliseconds(100)},
|
||||
timeOrigin,
|
||||
timeOrigin,
|
||||
0},
|
||||
{.name = "test2", .startTime = 0, .duration = 100}, 0, 0, 0},
|
||||
PerformanceEventTiming{
|
||||
{.name = "test4",
|
||||
.startTime = timeOrigin,
|
||||
.duration = HighResDuration::fromMilliseconds(100)},
|
||||
timeOrigin,
|
||||
timeOrigin,
|
||||
0},
|
||||
{.name = "test4", .startTime = 0, .duration = 100}, 0, 0, 0},
|
||||
};
|
||||
|
||||
ASSERT_EQ(expected, observer->takeRecords());
|
||||
@@ -358,71 +209,26 @@ TEST(PerformanceObserver, PerformanceObserverTestMultiple) {
|
||||
auto reporter = PerformanceEntryReporter::getInstance();
|
||||
reporter->clearEntries();
|
||||
|
||||
auto timeOrigin = HighResTimeStamp::now();
|
||||
auto observer1 =
|
||||
PerformanceObserver::create(reporter->getObserverRegistry(), [&]() {});
|
||||
auto observer2 =
|
||||
PerformanceObserver::create(reporter->getObserverRegistry(), [&]() {});
|
||||
observer1->observe(
|
||||
PerformanceEntryType::EVENT,
|
||||
{.durationThreshold = HighResDuration::fromMilliseconds(50)});
|
||||
observer2->observe(
|
||||
PerformanceEntryType::EVENT,
|
||||
{.durationThreshold = HighResDuration::fromMilliseconds(80)});
|
||||
observer1->observe(PerformanceEntryType::EVENT, {.durationThreshold = 50});
|
||||
observer2->observe(PerformanceEntryType::EVENT, {.durationThreshold = 80});
|
||||
|
||||
reporter->reportMeasure(
|
||||
"measure",
|
||||
timeOrigin,
|
||||
timeOrigin + HighResDuration::fromMilliseconds(50));
|
||||
reporter->reportEvent(
|
||||
"event1",
|
||||
timeOrigin,
|
||||
HighResDuration::fromMilliseconds(100),
|
||||
timeOrigin,
|
||||
timeOrigin,
|
||||
0);
|
||||
reporter->reportEvent(
|
||||
"event2",
|
||||
timeOrigin,
|
||||
HighResDuration::fromMilliseconds(40),
|
||||
timeOrigin,
|
||||
timeOrigin,
|
||||
0);
|
||||
reporter->reportMark(
|
||||
"mark1", timeOrigin + HighResDuration::fromMilliseconds(100));
|
||||
reporter->reportEvent(
|
||||
"event3",
|
||||
timeOrigin,
|
||||
HighResDuration::fromMilliseconds(60),
|
||||
timeOrigin,
|
||||
timeOrigin,
|
||||
0);
|
||||
reporter->reportMeasure("measure", 0, 50);
|
||||
reporter->reportEvent("event1", 0, 100, 0, 0, 0);
|
||||
reporter->reportEvent("event2", 0, 40, 0, 0, 0);
|
||||
reporter->reportMark("mark1", 100);
|
||||
reporter->reportEvent("event3", 0, 60, 0, 0, 0);
|
||||
|
||||
const std::vector<PerformanceEntry> expected1 = {
|
||||
PerformanceEventTiming{
|
||||
{.name = "event1",
|
||||
.startTime = timeOrigin,
|
||||
.duration = HighResDuration::fromMilliseconds(100)},
|
||||
timeOrigin,
|
||||
timeOrigin,
|
||||
0},
|
||||
PerformanceEventTiming{
|
||||
{.name = "event3",
|
||||
.startTime = timeOrigin,
|
||||
.duration = HighResDuration::fromMilliseconds(60)},
|
||||
timeOrigin,
|
||||
timeOrigin,
|
||||
0},
|
||||
PerformanceEventTiming{{.name = "event1", .duration = 100}, 0, 0, 0},
|
||||
PerformanceEventTiming{{.name = "event3", .duration = 60}, 0, 0, 0},
|
||||
};
|
||||
|
||||
const std::vector<PerformanceEntry> expected2 = {
|
||||
PerformanceEventTiming{
|
||||
{.name = "event1",
|
||||
.startTime = timeOrigin,
|
||||
.duration = HighResDuration::fromMilliseconds(100)},
|
||||
timeOrigin,
|
||||
timeOrigin,
|
||||
0},
|
||||
PerformanceEventTiming{{.name = "event1", .duration = 100}, 0, 0, 0},
|
||||
};
|
||||
|
||||
ASSERT_EQ(expected1, observer1->takeRecords());
|
||||
|
||||
@@ -34,7 +34,8 @@ class EventLogger {
|
||||
virtual EventTag onEventStart(
|
||||
std::string_view name,
|
||||
SharedEventTarget target,
|
||||
std::optional<HighResTimeStamp> eventStartTimeStamp = std::nullopt) = 0;
|
||||
std::optional<DOMHighResTimeStamp> eventStartTimeStamp =
|
||||
std::nullopt) = 0;
|
||||
|
||||
/*
|
||||
* Called when event starts getting dispatched (processed by the handlers, if
|
||||
|
||||
@@ -87,7 +87,7 @@ struct RawEvent {
|
||||
// The client may specify a platform-specific timestamp for the event start
|
||||
// time, for example when MotionEvent was triggered on the Android native
|
||||
// side.
|
||||
std::optional<HighResTimeStamp> eventStartTimeStamp = std::nullopt;
|
||||
std::optional<DOMHighResTimeStamp> eventStartTimeStamp = std::nullopt;
|
||||
};
|
||||
|
||||
} // namespace facebook::react
|
||||
|
||||
+1
-1
@@ -25,7 +25,7 @@ class MockEventLogger : public EventLogger {
|
||||
EventTag onEventStart(
|
||||
std::string_view /*name*/,
|
||||
SharedEventTarget /*target*/,
|
||||
std::optional<HighResTimeStamp> /*eventStartTimeStamp*/) override {
|
||||
std::optional<DOMHighResTimeStamp> /*eventStartTimeStamp*/) override {
|
||||
return EMPTY_EVENT_TAG;
|
||||
}
|
||||
void onEventProcessingStart(EventTag /*tag*/) override {}
|
||||
|
||||
+3
-3
@@ -105,7 +105,7 @@ EventPerformanceLogger::EventPerformanceLogger(
|
||||
EventTag EventPerformanceLogger::onEventStart(
|
||||
std::string_view name,
|
||||
SharedEventTarget target,
|
||||
std::optional<HighResTimeStamp> eventStartTimeStamp) {
|
||||
std::optional<DOMHighResTimeStamp> eventStartTimeStamp) {
|
||||
auto performanceEntryReporter = performanceEntryReporter_.lock();
|
||||
if (performanceEntryReporter == nullptr) {
|
||||
return EMPTY_EVENT_TAG;
|
||||
@@ -123,7 +123,7 @@ EventTag EventPerformanceLogger::onEventStart(
|
||||
|
||||
// The event start timestamp may be provided by the caller in order to
|
||||
// specify the platform specific event start time.
|
||||
HighResTimeStamp timeStamp = eventStartTimeStamp
|
||||
DOMHighResTimeStamp timeStamp = eventStartTimeStamp
|
||||
? *eventStartTimeStamp
|
||||
: performanceEntryReporter->getCurrentTimeStamp();
|
||||
{
|
||||
@@ -213,7 +213,7 @@ void EventPerformanceLogger::dispatchPendingEventTimingEntries(
|
||||
|
||||
void EventPerformanceLogger::shadowTreeDidMount(
|
||||
const RootShadowNode::Shared& rootShadowNode,
|
||||
HighResTimeStamp mountTime) noexcept {
|
||||
double mountTime) noexcept {
|
||||
auto performanceEntryReporter = performanceEntryReporter_.lock();
|
||||
if (performanceEntryReporter == nullptr) {
|
||||
return;
|
||||
|
||||
+5
-5
@@ -32,7 +32,7 @@ class EventPerformanceLogger : public EventLogger,
|
||||
EventTag onEventStart(
|
||||
std::string_view name,
|
||||
SharedEventTarget target,
|
||||
std::optional<HighResTimeStamp> eventStartTimeStamp =
|
||||
std::optional<DOMHighResTimeStamp> eventStartTimeStamp =
|
||||
std::nullopt) override;
|
||||
void onEventProcessingStart(EventTag tag) override;
|
||||
void onEventProcessingEnd(EventTag tag) override;
|
||||
@@ -47,15 +47,15 @@ class EventPerformanceLogger : public EventLogger,
|
||||
|
||||
void shadowTreeDidMount(
|
||||
const RootShadowNode::Shared& rootShadowNode,
|
||||
HighResTimeStamp mountTime) noexcept override;
|
||||
double mountTime) noexcept override;
|
||||
|
||||
private:
|
||||
struct EventEntry {
|
||||
std::string_view name;
|
||||
SharedEventTarget target{nullptr};
|
||||
HighResTimeStamp startTime;
|
||||
std::optional<HighResTimeStamp> processingStartTime;
|
||||
std::optional<HighResTimeStamp> processingEndTime;
|
||||
DOMHighResTimeStamp startTime;
|
||||
std::optional<DOMHighResTimeStamp> processingStartTime;
|
||||
std::optional<DOMHighResTimeStamp> processingEndTime;
|
||||
|
||||
bool isWaitingForMount{false};
|
||||
|
||||
|
||||
+4
-4
@@ -132,7 +132,7 @@ static Float getHighestThresholdCrossed(
|
||||
std::optional<IntersectionObserverEntry>
|
||||
IntersectionObserver::updateIntersectionObservation(
|
||||
const RootShadowNode& rootShadowNode,
|
||||
HighResTimeStamp time) {
|
||||
double time) {
|
||||
bool hasCustomRoot = observationRootShadowNodeFamily_.has_value();
|
||||
|
||||
auto rootAncestors = hasCustomRoot
|
||||
@@ -208,7 +208,7 @@ IntersectionObserver::updateIntersectionObservation(
|
||||
|
||||
std::optional<IntersectionObserverEntry>
|
||||
IntersectionObserver::updateIntersectionObservationForSurfaceUnmount(
|
||||
HighResTimeStamp time) {
|
||||
double time) {
|
||||
return setNotIntersectingState(Rect{}, Rect{}, Rect{}, time);
|
||||
}
|
||||
|
||||
@@ -219,7 +219,7 @@ IntersectionObserver::setIntersectingState(
|
||||
const Rect& intersectionRect,
|
||||
Float threshold,
|
||||
Float rootThreshold,
|
||||
HighResTimeStamp time) {
|
||||
double time) {
|
||||
auto newState =
|
||||
IntersectionObserverState::Intersecting(threshold, rootThreshold);
|
||||
|
||||
@@ -245,7 +245,7 @@ IntersectionObserver::setNotIntersectingState(
|
||||
const Rect& rootBoundingRect,
|
||||
const Rect& targetBoundingRect,
|
||||
const Rect& intersectionRect,
|
||||
HighResTimeStamp time) {
|
||||
double time) {
|
||||
if (state_ != IntersectionObserverState::NotIntersecting()) {
|
||||
state_ = IntersectionObserverState::NotIntersecting();
|
||||
IntersectionObserverEntry entry{
|
||||
|
||||
+7
-5
@@ -25,7 +25,9 @@ struct IntersectionObserverEntry {
|
||||
Rect rootRect;
|
||||
Rect intersectionRect;
|
||||
bool isIntersectingAboveThresholds;
|
||||
HighResTimeStamp time;
|
||||
// TODO(T156529385) Define `DOMHighResTimeStamp` as an alias for `double` and
|
||||
// use it here.
|
||||
double time;
|
||||
|
||||
bool sameShadowNodeFamily(
|
||||
const ShadowNodeFamily& otherShadowNodeFamily) const {
|
||||
@@ -47,10 +49,10 @@ class IntersectionObserver {
|
||||
// https://w3c.github.io/IntersectionObserver/#update-intersection-observations-algo
|
||||
std::optional<IntersectionObserverEntry> updateIntersectionObservation(
|
||||
const RootShadowNode& rootShadowNode,
|
||||
HighResTimeStamp time);
|
||||
double time);
|
||||
|
||||
std::optional<IntersectionObserverEntry>
|
||||
updateIntersectionObservationForSurfaceUnmount(HighResTimeStamp time);
|
||||
updateIntersectionObservationForSurfaceUnmount(double time);
|
||||
|
||||
IntersectionObserverObserverId getIntersectionObserverId() const {
|
||||
return intersectionObserverId_;
|
||||
@@ -71,13 +73,13 @@ class IntersectionObserver {
|
||||
const Rect& intersectionRect,
|
||||
Float threshold,
|
||||
Float rootThreshold,
|
||||
HighResTimeStamp time);
|
||||
double time);
|
||||
|
||||
std::optional<IntersectionObserverEntry> setNotIntersectingState(
|
||||
const Rect& rootBoundingRect,
|
||||
const Rect& targetBoundingRect,
|
||||
const Rect& intersectionRect,
|
||||
HighResTimeStamp time);
|
||||
double time);
|
||||
|
||||
IntersectionObserverObserverId intersectionObserverId_;
|
||||
std::optional<ShadowNodeFamily::Shared> observationRootShadowNodeFamily_;
|
||||
|
||||
+3
-3
@@ -283,14 +283,14 @@ void IntersectionObserverManager::updateIntersectionObservations(
|
||||
|
||||
void IntersectionObserverManager::shadowTreeDidMount(
|
||||
const RootShadowNode::Shared& rootShadowNode,
|
||||
HighResTimeStamp time) noexcept {
|
||||
double time) noexcept {
|
||||
updateIntersectionObservations(
|
||||
rootShadowNode->getSurfaceId(), rootShadowNode.get(), time);
|
||||
}
|
||||
|
||||
void IntersectionObserverManager::shadowTreeDidUnmount(
|
||||
SurfaceId surfaceId,
|
||||
HighResTimeStamp time) noexcept {
|
||||
double time) noexcept {
|
||||
updateIntersectionObservations(surfaceId, nullptr, time);
|
||||
}
|
||||
|
||||
@@ -299,7 +299,7 @@ void IntersectionObserverManager::shadowTreeDidUnmount(
|
||||
void IntersectionObserverManager::updateIntersectionObservations(
|
||||
SurfaceId surfaceId,
|
||||
const RootShadowNode* rootShadowNode,
|
||||
HighResTimeStamp time) {
|
||||
double time) {
|
||||
TraceSection s("IntersectionObserverManager::updateIntersectionObservations");
|
||||
|
||||
std::vector<IntersectionObserverEntry> entries;
|
||||
|
||||
+3
-4
@@ -56,10 +56,9 @@ class IntersectionObserverManager final
|
||||
|
||||
void shadowTreeDidMount(
|
||||
const RootShadowNode::Shared& rootShadowNode,
|
||||
HighResTimeStamp time) noexcept override;
|
||||
double time) noexcept override;
|
||||
|
||||
void shadowTreeDidUnmount(SurfaceId surfaceId, HighResTimeStamp time) noexcept
|
||||
override;
|
||||
void shadowTreeDidUnmount(SurfaceId surfaceId, double time) noexcept override;
|
||||
|
||||
private:
|
||||
mutable std::unordered_map<
|
||||
@@ -94,7 +93,7 @@ class IntersectionObserverManager final
|
||||
void updateIntersectionObservations(
|
||||
SurfaceId surfaceId,
|
||||
const RootShadowNode* rootShadowNode,
|
||||
HighResTimeStamp time);
|
||||
double time);
|
||||
|
||||
const IntersectionObserver& getRegisteredIntersectionObserver(
|
||||
SurfaceId surfaceId,
|
||||
|
||||
+6
-4
@@ -460,10 +460,12 @@ void RuntimeScheduler_Modern::reportLongTasks(
|
||||
return;
|
||||
}
|
||||
|
||||
if (longestPeriodWithoutYieldingOpportunity_ >=
|
||||
LONG_TASK_DURATION_THRESHOLD) {
|
||||
auto duration = endTime - startTime;
|
||||
reporter->reportLongTask(startTime, duration);
|
||||
auto checkedDurationMs =
|
||||
longestPeriodWithoutYieldingOpportunity_.toDOMHighResTimeStamp();
|
||||
if (checkedDurationMs >= LONG_TASK_DURATION_THRESHOLD_MS) {
|
||||
auto durationMs = (endTime - startTime).toDOMHighResTimeStamp();
|
||||
auto startTimeMs = startTime.toDOMHighResTimeStamp();
|
||||
reporter->reportLongTask(startTimeMs, durationMs);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+4
-8
@@ -12,7 +12,6 @@
|
||||
#include <react/featureflags/ReactNativeFeatureFlagsDefaults.h>
|
||||
#include <react/performance/timeline/PerformanceEntryReporter.h>
|
||||
#include <react/renderer/runtimescheduler/RuntimeScheduler.h>
|
||||
#include <chrono>
|
||||
#include <memory>
|
||||
#include <semaphore>
|
||||
#include <variant>
|
||||
@@ -1258,9 +1257,8 @@ TEST_P(RuntimeSchedulerTest, reportsLongTasks) {
|
||||
[startTime](const auto& entryDetails) {
|
||||
EXPECT_EQ(entryDetails.entryType, PerformanceEntryType::LONGTASK);
|
||||
EXPECT_EQ(
|
||||
entryDetails.startTime.toDOMHighResTimeStamp(),
|
||||
startTime.toDOMHighResTimeStamp() + 100);
|
||||
EXPECT_EQ(entryDetails.duration, HighResDuration::fromMilliseconds(50));
|
||||
entryDetails.startTime, startTime.toDOMHighResTimeStamp() + 100);
|
||||
EXPECT_EQ(entryDetails.duration, 50);
|
||||
},
|
||||
entry);
|
||||
}
|
||||
@@ -1346,10 +1344,8 @@ TEST_P(RuntimeSchedulerTest, reportsLongTasksWithYielding) {
|
||||
[startTime](const auto& entryDetails) {
|
||||
EXPECT_EQ(entryDetails.entryType, PerformanceEntryType::LONGTASK);
|
||||
EXPECT_EQ(
|
||||
entryDetails.startTime.toDOMHighResTimeStamp(),
|
||||
startTime.toDOMHighResTimeStamp() + 100);
|
||||
EXPECT_EQ(
|
||||
entryDetails.duration, HighResDuration::fromMilliseconds(120));
|
||||
entryDetails.startTime, startTime.toDOMHighResTimeStamp() + 100);
|
||||
EXPECT_EQ(entryDetails.duration, 120);
|
||||
},
|
||||
entry);
|
||||
}
|
||||
|
||||
@@ -26,11 +26,11 @@ class UIManagerMountHook {
|
||||
*/
|
||||
virtual void shadowTreeDidMount(
|
||||
const RootShadowNode::Shared& rootShadowNode,
|
||||
HighResTimeStamp mountTime) noexcept = 0;
|
||||
double mountTime) noexcept = 0;
|
||||
|
||||
virtual void shadowTreeDidUnmount(
|
||||
SurfaceId /*surfaceId*/,
|
||||
HighResTimeStamp /*unmountTime*/) noexcept {
|
||||
double /*unmountTime*/) noexcept {
|
||||
// Default no-op implementation for backwards compatibility.
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,23 @@
|
||||
|
||||
namespace facebook::react {
|
||||
|
||||
// `DOMHighResTimeStamp` represents a time value in milliseconds (time point or
|
||||
// duration), with sub-millisecond precision.
|
||||
// On the Web, the precision can be reduced for security purposes, but that is
|
||||
// not necessary in React Native.
|
||||
using DOMHighResTimeStamp = double;
|
||||
|
||||
inline DOMHighResTimeStamp chronoToDOMHighResTimeStamp(
|
||||
std::chrono::steady_clock::duration duration) {
|
||||
return static_cast<std::chrono::duration<double, std::milli>>(duration)
|
||||
.count();
|
||||
}
|
||||
|
||||
inline DOMHighResTimeStamp chronoToDOMHighResTimeStamp(
|
||||
std::chrono::steady_clock::time_point timePoint) {
|
||||
return chronoToDOMHighResTimeStamp(timePoint.time_since_epoch());
|
||||
}
|
||||
|
||||
class HighResDuration;
|
||||
class HighResTimeStamp;
|
||||
|
||||
|
||||
@@ -11,6 +11,39 @@
|
||||
|
||||
namespace facebook::react {
|
||||
|
||||
using Clock = std::chrono::steady_clock;
|
||||
using TimePoint = std::chrono::time_point<Clock>;
|
||||
|
||||
TEST(chronoToDOMHighResTimeStamp, withDurations) {
|
||||
EXPECT_EQ(chronoToDOMHighResTimeStamp(std::chrono::nanoseconds(10)), 0.00001);
|
||||
EXPECT_EQ(chronoToDOMHighResTimeStamp(std::chrono::microseconds(10)), 0.01);
|
||||
EXPECT_EQ(chronoToDOMHighResTimeStamp(std::chrono::milliseconds(10)), 10.0);
|
||||
EXPECT_EQ(chronoToDOMHighResTimeStamp(std::chrono::seconds(10)), 10000.0);
|
||||
EXPECT_EQ(
|
||||
chronoToDOMHighResTimeStamp(
|
||||
std::chrono::seconds(1) + std::chrono::nanoseconds(20)),
|
||||
1000.000020);
|
||||
}
|
||||
|
||||
TEST(chronoToDOMHighResTimeStamp, withTimePoints) {
|
||||
EXPECT_EQ(
|
||||
chronoToDOMHighResTimeStamp(TimePoint(std::chrono::nanoseconds(10))),
|
||||
0.00001);
|
||||
EXPECT_EQ(
|
||||
chronoToDOMHighResTimeStamp(TimePoint(std::chrono::microseconds(10))),
|
||||
0.01);
|
||||
EXPECT_EQ(
|
||||
chronoToDOMHighResTimeStamp(TimePoint(std::chrono::milliseconds(10))),
|
||||
10.0);
|
||||
EXPECT_EQ(
|
||||
chronoToDOMHighResTimeStamp(TimePoint(std::chrono::seconds(10))),
|
||||
10000.0);
|
||||
EXPECT_EQ(
|
||||
chronoToDOMHighResTimeStamp(
|
||||
TimePoint(std::chrono::seconds(1) + std::chrono::nanoseconds(20))),
|
||||
1000.000020);
|
||||
}
|
||||
|
||||
TEST(HighResDuration, CorrectlyConvertsToDOMHighResTimeStamp) {
|
||||
EXPECT_EQ(
|
||||
HighResDuration::fromNanoseconds(10).toDOMHighResTimeStamp(), 0.00001);
|
||||
|
||||
+1
-1
@@ -113,7 +113,7 @@ void HermesPerfettoDataSource::OnStart(const StartArgs&) {
|
||||
"react-native",
|
||||
perfetto::DynamicString{"Profiling Started"},
|
||||
getPerfettoWebPerfTrackSync("JS Sampling"),
|
||||
perfetto::TrackEvent::GetTraceTimeNs());
|
||||
performanceNowToPerfettoTraceTime(0));
|
||||
}
|
||||
|
||||
void HermesPerfettoDataSource::OnFlush(const FlushArgs&) {
|
||||
|
||||
+6
-10
@@ -80,17 +80,13 @@ perfetto::Track getPerfettoWebPerfTrackAsync(const std::string& trackName) {
|
||||
}
|
||||
|
||||
// Perfetto's monotonic clock seems to match the std::chrono::steady_clock we
|
||||
// use in HighResTimeStamp on Android platforms, but if that
|
||||
// use in JSExecutor::performanceNow on Android platforms, but if that
|
||||
// assumption is incorrect we may need to manually offset perfetto timestamps.
|
||||
uint64_t highResTimeStampToPerfettoTraceTime(HighResTimeStamp timestamp) {
|
||||
auto chronoDurationSinceSteadyClockEpoch =
|
||||
timestamp.toChronoSteadyClockTimePoint().time_since_epoch();
|
||||
auto nanoseconds = std::chrono::duration_cast<std::chrono::nanoseconds>(
|
||||
chronoDurationSinceSteadyClockEpoch);
|
||||
|
||||
return std::chrono::duration_cast<std::chrono::duration<std::uint64_t>>(
|
||||
nanoseconds)
|
||||
.count();
|
||||
uint64_t performanceNowToPerfettoTraceTime(double perfNowTime) {
|
||||
if (perfNowTime == 0) {
|
||||
return perfetto::TrackEvent::GetTraceTimeNs();
|
||||
}
|
||||
return static_cast<uint64_t>(perfNowTime * 1.e6);
|
||||
}
|
||||
|
||||
} // namespace facebook::react
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
#ifdef WITH_PERFETTO
|
||||
|
||||
#include <perfetto.h>
|
||||
#include <react/timing/primitives.h>
|
||||
#include <reactperflogger/ReactPerfettoCategories.h>
|
||||
#include <string>
|
||||
|
||||
@@ -21,7 +20,7 @@ void initializePerfetto();
|
||||
perfetto::Track getPerfettoWebPerfTrackSync(const std::string& trackName);
|
||||
perfetto::Track getPerfettoWebPerfTrackAsync(const std::string& trackName);
|
||||
|
||||
uint64_t highResTimeStampToPerfettoTraceTime(HighResTimeStamp timestamp);
|
||||
uint64_t performanceNowToPerfettoTraceTime(double perfNowTime);
|
||||
|
||||
} // namespace facebook::react
|
||||
|
||||
|
||||
+12
-9
@@ -13,6 +13,8 @@
|
||||
#include <fbsystrace.h>
|
||||
#endif
|
||||
|
||||
#include <chrono>
|
||||
|
||||
namespace facebook::react {
|
||||
|
||||
namespace {
|
||||
@@ -28,9 +30,10 @@ std::string toPerfettoTrackName(
|
||||
: PERFETTO_DEFAULT_TRACK_NAME;
|
||||
}
|
||||
#elif defined(WITH_FBSYSTRACE)
|
||||
int64_t getDeltaNanos(HighResTimeStamp jsTime) {
|
||||
auto now = HighResTimeStamp::now();
|
||||
return (jsTime - now).toNanoseconds();
|
||||
int64_t getDeltaNanos(double jsTime) {
|
||||
auto now = std::chrono::steady_clock::now().time_since_epoch();
|
||||
return static_cast<int64_t>(jsTime * 1.e6) -
|
||||
std::chrono::duration_cast<std::chrono::nanoseconds>(now).count();
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -48,8 +51,8 @@ int64_t getDeltaNanos(HighResTimeStamp jsTime) {
|
||||
|
||||
/* static */ void ReactPerfettoLogger::measure(
|
||||
const std::string_view& eventName,
|
||||
HighResTimeStamp startTime,
|
||||
HighResTimeStamp endTime,
|
||||
double startTime,
|
||||
double endTime,
|
||||
const std::optional<std::string_view>& trackName) {
|
||||
#if defined(WITH_PERFETTO)
|
||||
if (TRACE_EVENT_CATEGORY_ENABLED("react-native")) {
|
||||
@@ -58,9 +61,9 @@ int64_t getDeltaNanos(HighResTimeStamp jsTime) {
|
||||
"react-native",
|
||||
perfetto::DynamicString(eventName.data(), eventName.size()),
|
||||
track,
|
||||
highResTimeStampToPerfettoTraceTime(startTime));
|
||||
performanceNowToPerfettoTraceTime(startTime));
|
||||
TRACE_EVENT_END(
|
||||
"react-native", track, highResTimeStampToPerfettoTraceTime(endTime));
|
||||
"react-native", track, performanceNowToPerfettoTraceTime(endTime));
|
||||
}
|
||||
#elif defined(WITH_FBSYSTRACE)
|
||||
static int cookie = 0;
|
||||
@@ -74,7 +77,7 @@ int64_t getDeltaNanos(HighResTimeStamp jsTime) {
|
||||
|
||||
/* static */ void ReactPerfettoLogger::mark(
|
||||
const std::string_view& eventName,
|
||||
HighResTimeStamp startTime,
|
||||
double startTime,
|
||||
const std::optional<std::string_view>& trackName) {
|
||||
#if defined(WITH_PERFETTO)
|
||||
if (TRACE_EVENT_CATEGORY_ENABLED("react-native")) {
|
||||
@@ -82,7 +85,7 @@ int64_t getDeltaNanos(HighResTimeStamp jsTime) {
|
||||
"react-native",
|
||||
perfetto::DynamicString(eventName.data(), eventName.size()),
|
||||
getPerfettoWebPerfTrackSync(toPerfettoTrackName(trackName)),
|
||||
highResTimeStampToPerfettoTraceTime(startTime));
|
||||
performanceNowToPerfettoTraceTime(startTime));
|
||||
}
|
||||
#elif defined(WITH_FBSYSTRACE)
|
||||
static const char* kTrackName = "# Web Performance: Markers";
|
||||
|
||||
+3
-4
@@ -7,7 +7,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <react/timing/primitives.h>
|
||||
#include <reactperflogger/ReactPerfettoCategories.h>
|
||||
|
||||
#include <optional>
|
||||
@@ -25,13 +24,13 @@ class ReactPerfettoLogger {
|
||||
|
||||
static void mark(
|
||||
const std::string_view& eventName,
|
||||
HighResTimeStamp startTime,
|
||||
double startTime,
|
||||
const std::optional<std::string_view>& trackName);
|
||||
|
||||
static void measure(
|
||||
const std::string_view& eventName,
|
||||
HighResTimeStamp startTime,
|
||||
HighResTimeStamp endTime,
|
||||
double startTime,
|
||||
double endTime,
|
||||
const std::optional<std::string_view>& trackName);
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user