diff --git a/packages/react-native/ReactCommon/react/performance/cdpmetrics/CdpInteractionTypes.cpp b/packages/react-native/ReactCommon/react/performance/cdpmetrics/CdpInteractionTypes.cpp new file mode 100644 index 00000000000..3669153a588 --- /dev/null +++ b/packages/react-native/ReactCommon/react/performance/cdpmetrics/CdpInteractionTypes.cpp @@ -0,0 +1,63 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#include "CdpInteractionTypes.h" + +namespace facebook::react { + +const InteractionTypesMap& getInteractionTypes() { + static InteractionTypesMap INTERACTION_TYPES = { + {"auxclick", "pointer"}, + {"click", "pointer"}, + {"contextmenu", "pointer"}, + {"dblclick", "pointer"}, + {"mousedown", "pointer"}, + {"mouseenter", "pointer"}, + {"mouseleave", "pointer"}, + {"mouseout", "pointer"}, + {"mouseover", "pointer"}, + {"mouseup", "pointer"}, + {"pointerover", "pointer"}, + {"pointerenter", "pointer"}, + {"pointerdown", "pointer"}, + {"pointerup", "pointer"}, + {"pointercancel", "pointer"}, + {"pointerout", "pointer"}, + {"pointerleave", "pointer"}, + {"gotpointercapture", "pointer"}, + {"lostpointercapture", "pointer"}, + {"touchstart", "touch"}, + {"touchend", "touch"}, + {"touchcancel", "touch"}, + {"keydown", "keyboard"}, + {"keypress", "keyboard"}, + {"keyup", "keyboard"}, + {"beforeinput", "keyboard"}, + {"input", "keyboard"}, + {"compositionstart", "composition"}, + {"compositionupdate", "composition"}, + {"compositionend", "composition"}, + {"dragstart", "drag"}, + {"dragend", "drag"}, + {"dragenter", "drag"}, + {"dragleave", "drag"}, + {"dragover", "drag"}, + {"drop", "drag"}, + }; + return INTERACTION_TYPES; +} + +const std::string_view getInteractionTypeForEvent(std::string_view eventName) { + const auto& interactionTypes = getInteractionTypes(); + auto it = interactionTypes.find(eventName); + if (it != interactionTypes.end()) { + return it->second; + } + return "unknown"; +} + +} // namespace facebook::react diff --git a/packages/react-native/ReactCommon/react/performance/cdpmetrics/CdpInteractionTypes.h b/packages/react-native/ReactCommon/react/performance/cdpmetrics/CdpInteractionTypes.h new file mode 100644 index 00000000000..a2d67265f86 --- /dev/null +++ b/packages/react-native/ReactCommon/react/performance/cdpmetrics/CdpInteractionTypes.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include +#include + +namespace facebook::react { + +using InteractionTypesMap = + std::unordered_map; + +const InteractionTypesMap& getInteractionTypes(); + +const std::string_view getInteractionTypeForEvent(std::string_view eventName); + +} // namespace facebook::react diff --git a/packages/react-native/ReactCommon/react/performance/cdpmetrics/CdpMetricsReporter.cpp b/packages/react-native/ReactCommon/react/performance/cdpmetrics/CdpMetricsReporter.cpp index 9dd5687bf39..9c09a8509cb 100644 --- a/packages/react-native/ReactCommon/react/performance/cdpmetrics/CdpMetricsReporter.cpp +++ b/packages/react-native/ReactCommon/react/performance/cdpmetrics/CdpMetricsReporter.cpp @@ -6,6 +6,7 @@ */ #include "CdpMetricsReporter.h" +#include "CdpInteractionTypes.h" #include #include @@ -31,15 +32,32 @@ void CdpMetricsReporter::onEventTimingEntry( return; } + auto inputDelay = entry.processingStart - entry.startTime; + auto processingDuration = entry.processingEnd - entry.processingStart; + auto nextPaintTime = entry.startTime + entry.duration; + auto presentationDelay = nextPaintTime - entry.processingEnd; + folly::dynamic jsonPayload = folly::dynamic::object; - jsonPayload["eventName"] = entry.name; - jsonPayload["durationMs"] = + jsonPayload["name"] = "InteractionEntry"; + jsonPayload["duration"] = static_cast(entry.duration.toDOMHighResTimeStamp()); + jsonPayload["phases"] = folly::dynamic::object( + "inputDelay", static_cast(inputDelay.toDOMHighResTimeStamp()))( + "processingDuration", + static_cast(processingDuration.toDOMHighResTimeStamp()))( + "presentationDelay", + static_cast(presentationDelay.toDOMHighResTimeStamp())); jsonPayload["startTime"] = static_cast(entry.startTime.toDOMHighResTimeStamp()); + jsonPayload["nextPaintTime"] = + static_cast(nextPaintTime.toDOMHighResTimeStamp()); + jsonPayload["interactionType"] = + std::string(getInteractionTypeForEvent(entry.name)); + jsonPayload["eventName"] = std::string(entry.name); + jsonPayload["longAnimationFrameEntries"] = folly::dynamic::array(); + auto jsonString = folly::toJson(jsonPayload); auto jsiString = jsi::String::createFromUtf8(runtime, jsonString); - auto metricsReporter = global.getPropertyAsFunction(runtime, metricsReporterName.data()); metricsReporter.call(runtime, jsiString);