mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Scaffolding for the PerformanceObserver TurboModule (C++ side) (#35226)
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/35226 Changelog: [Internal] This adds scaffolding for the C++ side of NativePerformanceObserver module. Thanks to christophpurrer for helping set this up, as this is the first one of this kind inside core/OSS. Reviewed By: rubennorte Differential Revision: D41028555 fbshipit-source-id: 4acf0e71a254a42044cbbe5f94f40938342c6aa2
This commit is contained in:
committed by
Facebook GitHub Bot
parent
ea1d72921d
commit
ea73a66936
@@ -10,6 +10,9 @@ load(
|
||||
)
|
||||
load(
|
||||
"//tools/build_defs/oss:rn_defs.bzl",
|
||||
"ANDROID",
|
||||
"APPLE",
|
||||
"CXX",
|
||||
"HERMES_BYTECODE_VERSION",
|
||||
"IOS",
|
||||
"RCT_IMAGE_DATA_DECODER_SOCKET",
|
||||
@@ -1453,3 +1456,28 @@ rn_xplat_cxx_library2(
|
||||
"//fbobjc/VendorLib/react-native-maps:react-native-maps",
|
||||
],
|
||||
)
|
||||
|
||||
rn_xplat_cxx_library2(
|
||||
name = "RCTWebPerformance",
|
||||
srcs = glob([
|
||||
"Libraries/WebPerformance/**/*.cpp",
|
||||
]),
|
||||
header_namespace = "",
|
||||
exported_headers = subdir_glob(
|
||||
[("Libraries/WebPerformance", "*.h")],
|
||||
prefix = "RCTWebPerformance",
|
||||
),
|
||||
fbandroid_compiler_flags = [
|
||||
"-fexceptions",
|
||||
"-frtti",
|
||||
],
|
||||
labels = [
|
||||
"depslint_never_remove",
|
||||
"pfh:ReactNative_CommonInfrastructurePlaceholder",
|
||||
],
|
||||
platforms = (ANDROID, APPLE, CXX),
|
||||
visibility = ["PUBLIC"],
|
||||
deps = [
|
||||
":FBReactNativeSpecJSI",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* 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 "NativePerformanceObserver.h"
|
||||
#include <glog/logging.h>
|
||||
|
||||
namespace facebook::react {
|
||||
|
||||
NativePerformanceObserver::NativePerformanceObserver(
|
||||
std::shared_ptr<CallInvoker> jsInvoker)
|
||||
: NativePerformanceObserverCxxSpec(std::move(jsInvoker)) {}
|
||||
|
||||
void NativePerformanceObserver::startReporting(
|
||||
jsi::Runtime &rt,
|
||||
std::string entryType) {
|
||||
LOG(INFO) << "Started reporting perf entry type: " << entryType;
|
||||
}
|
||||
|
||||
void NativePerformanceObserver::stopReporting(
|
||||
jsi::Runtime &rt,
|
||||
std::string entryType) {
|
||||
LOG(INFO) << "Stopped reporting perf entry type: " << entryType;
|
||||
}
|
||||
|
||||
std::vector<RawPerformanceEntry> NativePerformanceObserver::getPendingEntries(
|
||||
jsi::Runtime &rt) {
|
||||
return std::vector<RawPerformanceEntry>{};
|
||||
}
|
||||
|
||||
void NativePerformanceObserver::setOnPerformanceEntryCallback(
|
||||
jsi::Runtime &rt,
|
||||
std::optional<AsyncCallback<>> callback) {
|
||||
callback_ = callback;
|
||||
LOG(INFO) << "setOnPerformanceEntryCallback: "
|
||||
<< (callback ? "non-empty" : "empty");
|
||||
}
|
||||
|
||||
} // namespace facebook::react
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* 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 <FBReactNativeSpec/FBReactNativeSpecJSI.h>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "NativePerformanceObserver_RawPerformanceEntry.h"
|
||||
|
||||
namespace facebook::react {
|
||||
|
||||
class NativePerformanceObserver
|
||||
: public NativePerformanceObserverCxxSpec<NativePerformanceObserver>,
|
||||
std::enable_shared_from_this<NativePerformanceObserver> {
|
||||
public:
|
||||
NativePerformanceObserver(std::shared_ptr<CallInvoker> jsInvoker);
|
||||
|
||||
void startReporting(jsi::Runtime &rt, std::string entryType);
|
||||
|
||||
void stopReporting(jsi::Runtime &rt, std::string entryType);
|
||||
|
||||
std::vector<RawPerformanceEntry> getPendingEntries(jsi::Runtime &rt);
|
||||
|
||||
void setOnPerformanceEntryCallback(
|
||||
jsi::Runtime &rt,
|
||||
std::optional<AsyncCallback<>> callback);
|
||||
|
||||
private:
|
||||
std::optional<AsyncCallback<>> callback_;
|
||||
};
|
||||
|
||||
} // namespace facebook::react
|
||||
+10
-13
@@ -8,11 +8,9 @@
|
||||
* @format
|
||||
*/
|
||||
|
||||
import type {TurboModule} from '../../TurboModule/RCTExport';
|
||||
import type {TurboModule} from '../TurboModule/RCTExport';
|
||||
|
||||
import * as TurboModuleRegistry from '../../TurboModule/TurboModuleRegistry';
|
||||
|
||||
export type RawTimeStamp = number;
|
||||
import * as TurboModuleRegistry from '../TurboModule/TurboModuleRegistry';
|
||||
|
||||
export const RawPerformanceEntryTypeValues = {
|
||||
UNDEFINED: 0,
|
||||
@@ -23,22 +21,21 @@ export type RawPerformanceEntryType = number;
|
||||
export type RawPerformanceEntry = $ReadOnly<{
|
||||
name: string,
|
||||
entryType: RawPerformanceEntryType,
|
||||
startTime: RawTimeStamp,
|
||||
startTime: number,
|
||||
duration: number,
|
||||
|
||||
// For "event" entries only:
|
||||
processingStart?: RawTimeStamp,
|
||||
processingEnd?: RawTimeStamp,
|
||||
interactionId?: RawTimeStamp,
|
||||
processingStart?: number,
|
||||
processingEnd?: number,
|
||||
interactionId?: number,
|
||||
}>;
|
||||
|
||||
export type RawPerformanceEntryList = $ReadOnlyArray<RawPerformanceEntry>;
|
||||
|
||||
export interface Spec extends TurboModule {
|
||||
+startReporting: (entryType: string) => void;
|
||||
+stopReporting: (entryType: string) => void;
|
||||
+getPendingEntries: () => RawPerformanceEntryList;
|
||||
+getPendingEntries: () => $ReadOnlyArray<RawPerformanceEntry>;
|
||||
+setOnPerformanceEntryCallback: (callback?: () => void) => void;
|
||||
}
|
||||
|
||||
export default (TurboModuleRegistry.get<Spec>('PerformanceObserver'): ?Spec);
|
||||
export default (TurboModuleRegistry.get<Spec>(
|
||||
'NativePerformanceObserverCxx',
|
||||
): ?Spec);
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* 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 <react/bridging/Bridging.h>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
namespace facebook::react {
|
||||
|
||||
struct RawPerformanceEntry {
|
||||
std::string name;
|
||||
int32_t entryType;
|
||||
double startTime;
|
||||
double duration;
|
||||
// For "event" entries only:
|
||||
std::optional<double> processingStart;
|
||||
std::optional<double> processingEnd;
|
||||
std::optional<double> interactionId;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Bridging<RawPerformanceEntry> {
|
||||
static RawPerformanceEntry fromJs(
|
||||
jsi::Runtime &rt,
|
||||
const jsi::Object &value,
|
||||
const std::shared_ptr<CallInvoker> &jsInvoker) {
|
||||
RawPerformanceEntry result{
|
||||
bridging::fromJs<std::string>(
|
||||
rt, value.getProperty(rt, "name"), jsInvoker),
|
||||
bridging::fromJs<int32_t>(
|
||||
rt, value.getProperty(rt, "entryType"), jsInvoker),
|
||||
bridging::fromJs<double>(
|
||||
rt, value.getProperty(rt, "startTime"), jsInvoker),
|
||||
bridging::fromJs<double>(
|
||||
rt, value.getProperty(rt, "duration"), jsInvoker),
|
||||
bridging::fromJs<std::optional<double>>(
|
||||
rt, value.getProperty(rt, "processingStart"), jsInvoker),
|
||||
bridging::fromJs<std::optional<double>>(
|
||||
rt, value.getProperty(rt, "processingEnd"), jsInvoker),
|
||||
bridging::fromJs<std::optional<double>>(
|
||||
rt, value.getProperty(rt, "interactionId"), jsInvoker),
|
||||
};
|
||||
return result;
|
||||
}
|
||||
|
||||
static jsi::Object toJs(jsi::Runtime &rt, const RawPerformanceEntry &value) {
|
||||
auto result = facebook::jsi::Object(rt);
|
||||
result.setProperty(rt, "name", bridging::toJs(rt, value.name));
|
||||
result.setProperty(rt, "entryType", bridging::toJs(rt, value.entryType));
|
||||
result.setProperty(rt, "startTime", bridging::toJs(rt, value.startTime));
|
||||
result.setProperty(rt, "duration", bridging::toJs(rt, value.duration));
|
||||
if (value.processingStart) {
|
||||
result.setProperty(
|
||||
rt,
|
||||
"processingStart",
|
||||
bridging::toJs(rt, value.processingStart.value()));
|
||||
}
|
||||
if (value.processingEnd) {
|
||||
result.setProperty(
|
||||
rt, "processingEnd", bridging::toJs(rt, value.processingEnd.value()));
|
||||
}
|
||||
if (value.interactionId) {
|
||||
result.setProperty(
|
||||
rt, "interactionId", bridging::toJs(rt, value.interactionId.value()));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace facebook::react
|
||||
@@ -10,12 +10,11 @@
|
||||
|
||||
import type {
|
||||
RawPerformanceEntry,
|
||||
RawPerformanceEntryList,
|
||||
RawPerformanceEntryType,
|
||||
} from '../NativeModules/specs/NativePerformanceObserverCxx';
|
||||
} from './NativePerformanceObserver';
|
||||
|
||||
import NativePerformanceObserver from '../NativeModules/specs/NativePerformanceObserverCxx';
|
||||
import warnOnce from '../Utilities/warnOnce';
|
||||
import NativePerformanceObserver from './NativePerformanceObserver';
|
||||
|
||||
export type HighResTimeStamp = number;
|
||||
// TODO: Extend once new types (such as event) are supported.
|
||||
@@ -195,7 +194,7 @@ export default class PerformanceObserver {
|
||||
});
|
||||
_observers.delete(this);
|
||||
if (_observers.size === 0) {
|
||||
NativePerformanceObserver.setOnPerformanceEntryCallback();
|
||||
NativePerformanceObserver.setOnPerformanceEntryCallback(undefined);
|
||||
_onPerformanceEntryCallbackIsSet = false;
|
||||
}
|
||||
}
|
||||
@@ -210,8 +209,7 @@ function onPerformanceEntry() {
|
||||
if (!NativePerformanceObserver) {
|
||||
return;
|
||||
}
|
||||
const rawEntries: RawPerformanceEntryList =
|
||||
NativePerformanceObserver.getPendingEntries();
|
||||
const rawEntries = NativePerformanceObserver.getPendingEntries();
|
||||
const entries = rawEntries.map(rawToPerformanceEntry);
|
||||
_observers.forEach(observer => {
|
||||
const entriesForObserver: PerformanceEntryList = entries.filter(entry =>
|
||||
|
||||
Reference in New Issue
Block a user