Skip to content

Commit

Permalink
Add React Native perf metrics behind flag (#16)
Browse files Browse the repository at this point in the history
  • Loading branch information
EdmondChuiHW authored Mar 12, 2024
1 parent 8c5e07a commit 72a0dbf
Show file tree
Hide file tree
Showing 11 changed files with 99 additions and 2 deletions.
1 change: 1 addition & 0 deletions config/gni/devtools_grd_files.gni
Original file line number Diff line number Diff line change
Expand Up @@ -701,6 +701,7 @@ grd_files_debug_sources = [
"front_end/core/host/InspectorFrontendHost.js",
"front_end/core/host/InspectorFrontendHostAPI.js",
"front_end/core/host/Platform.js",
"front_end/core/host/RNPerfMetrics.js",
"front_end/core/host/ResourceLoader.js",
"front_end/core/host/UserMetrics.js",
"front_end/core/i18n/DevToolsLocale.js",
Expand Down
1 change: 1 addition & 0 deletions front_end/core/host/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ devtools_module("host") {
"InspectorFrontendHost.ts",
"InspectorFrontendHostAPI.ts",
"Platform.ts",
"RNPerfMetrics.ts",
"ResourceLoader.ts",
"UserMetrics.ts",
]
Expand Down
73 changes: 73 additions & 0 deletions front_end/core/host/RNPerfMetrics.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// Copyright (c) Meta Platforms, Inc. and affiliates.
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

export type RNReliabilityEventListener = (event: ReactNativeChromeDevToolsEvent) => void;

type UnsunscribeFn = () => void;
export type RNPerfMetrics = {
addEventListener: (listener: RNReliabilityEventListener) => UnsunscribeFn,
removeAllEventListeners: () => void,
sendEvent: (event: ReactNativeChromeDevToolsEvent) => void,
};

let instance: RNPerfMetrics|null = null;

export function getInstance(): RNPerfMetrics {
if (instance === null) {
instance = new RNPerfMetricsImpl();
}
return instance;
}

class RNPerfMetricsImpl implements RNPerfMetrics {
#listeners: Set<RNReliabilityEventListener> = new Set();

addEventListener(listener: RNReliabilityEventListener): () => void {
this.#listeners.add(listener);

const unsubscribe = (): void => {
this.#listeners.delete(listener);
};

return unsubscribe;
}

removeAllEventListeners(): void {
this.#listeners.clear();
}

sendEvent(event: ReactNativeChromeDevToolsEvent): void {
if (globalThis.enableReactNativePerfMetrics !== true) {
return;
}

const errors = [];
for (const listener of this.#listeners) {
try {
listener(event);
} catch (e) {
errors.push(e);
}
}

if (errors.length > 0) {
const error = new AggregateError(errors);
console.error('Error occurred when calling event listeners', error);
}
}
}

export function registerPerfMetricsGlobalPostMessageHandler(): void {
if (globalThis.enableReactNativePerfMetrics !== true ||
globalThis.enableReactNativePerfMetricsGlobalPostMessage !== true) {
return;
}

getInstance().addEventListener(event => {
window.postMessage({event, tag: 'react-native-chrome-devtools-perf-metrics'}, window.location.origin);
});
}

export type ReactNativeChromeDevToolsEvent = {};
3 changes: 3 additions & 0 deletions front_end/core/host/host.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,17 @@ import * as InspectorFrontendHost from './InspectorFrontendHost.js';
import * as InspectorFrontendHostAPI from './InspectorFrontendHostAPI.js';
import * as Platform from './Platform.js';
import * as ResourceLoader from './ResourceLoader.js';
import * as RNPerfMetrics from './RNPerfMetrics.js';
import * as UserMetrics from './UserMetrics.js';

export {
InspectorFrontendHost,
InspectorFrontendHostAPI,
Platform,
ResourceLoader,
RNPerfMetrics,
UserMetrics,
};

export const userMetrics = new UserMetrics.UserMetrics();
export const rnPerfMetrics = RNPerfMetrics.getInstance();
2 changes: 1 addition & 1 deletion front_end/entrypoint_template.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,6 @@
<meta http-equiv="Content-Security-Policy" content="object-src 'none'; script-src 'self' 'unsafe-eval' https://chrome-devtools-frontend.appspot.com">
<meta name="referrer" content="no-referrer">
<link rel="icon" href="./Images/favicon.ico">
<script async src="./embedder-static/embedderScript.js"></script>
<script defer src="./embedder-static/embedderScript.js"></script>
<script type="module" src="./entrypoints/%ENTRYPOINT_NAME%/%ENTRYPOINT_NAME%.js"></script>
<body class="undocked" id="-blink-dev-tools">
1 change: 1 addition & 0 deletions front_end/entrypoints/rn_inspector/BUILD.gn
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# Copyright (c) Meta Platforms, Inc. and affiliates.
# Copyright 2021 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
Expand Down
3 changes: 3 additions & 0 deletions front_end/entrypoints/rn_inspector/rn_inspector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,12 @@ import '../../panels/network/network-meta.js';
import '../../panels/js_profiler/js_profiler-meta.js';
import '../../panels/rn_welcome/rn_welcome-meta.js';

import * as Host from '../../core/host/host.js';
import * as Root from '../../core/root/root.js';
import * as Main from '../main/main.js';

Host.RNPerfMetrics.registerPerfMetricsGlobalPostMessageHandler();

// Legacy JavaScript Profiler - we support this until Hermes can support the
// modern Performance panel.
Root.Runtime.experiments.register(
Expand Down
1 change: 1 addition & 0 deletions front_end/global_typings/global_defs.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// found in the LICENSE file.

/// <reference path="./request_idle_callback.d.ts" />
/// <reference path="./react_native.d.ts" />

interface CSSStyleSheet {
replaceSync(content: string): void;
Expand Down
13 changes: 13 additions & 0 deletions front_end/global_typings/react_native.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Copyright (c) Meta Platforms, Inc. and affiliates.
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

export {};

declare global {
namespace globalThis {
var enableReactNativePerfMetrics: boolean|undefined;
var enableReactNativePerfMetricsGlobalPostMessage: boolean|undefined;
}
}
1 change: 1 addition & 0 deletions scripts/eslint_rules/lib/check_license_header.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ const EXCLUDED_FILES = [
const META_CODE_PATHS = [
'entrypoints/rn_inspector',
'panels/rn_welcome',
'core/host/RNPerfMetrics.ts',
];

const OTHER_LICENSE_HEADERS = [
Expand Down
2 changes: 1 addition & 1 deletion scripts/eslint_rules/lib/no_bound_component_methods.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ module.exports = {
callExpressionNode) {
const methodArg = callExpressionNode.arguments[1];
// Confirm that the argument is this.X, otherwise skip it
if (methodArg.type !== 'MemberExpression') {
if (methodArg?.type !== 'MemberExpression') {
return;
}

Expand Down

0 comments on commit 72a0dbf

Please sign in to comment.