Skip to content

Commit

Permalink
Convert Performance to single default export
Browse files Browse the repository at this point in the history
  • Loading branch information
kidroca committed Aug 23, 2021
1 parent 4427cd9 commit 9ea80ba
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 50 deletions.
69 changes: 31 additions & 38 deletions src/libs/Performance.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import getComponentDisplayName from './getComponentDisplayName';
import CONST from '../CONST';

/** @type {import('react-native-performance').Performance} */
let performance;
let rnPerformance;

/**
* Deep diff between two objects. Useful for figuring out what changed about an object from one render to the next so
Expand All @@ -33,40 +33,41 @@ function diffObject(object, base) {
return changes(object, base);
}

// When performance monitoring is disabled the implementations are blank
/* eslint-disable import/no-mutable-exports */
let setupPerformanceObserver = () => {};
let printPerformanceMetrics = () => {};
let markStart = () => {};
let markEnd = () => {};
let traceRender = () => {};
let withRenderTrace = () => Component => Component;
/* eslint-enable import/no-mutable-exports */
const Performance = {
// When performance monitoring is disabled the implementations are blank
diffObject,
setupPerformanceObserver: () => {},
printPerformanceMetrics: () => {},
markStart: () => {},
markEnd: () => {},
traceRender: () => {},
withRenderTrace: () => Component => Component,
};

if (canCapturePerformanceMetrics()) {
/**
* Sets up an observer to capture events recorded in the native layer before the app fully initializes.
*/
setupPerformanceObserver = () => {
Performance.setupPerformanceObserver = () => {
const performanceReported = require('react-native-performance-flipper-reporter');
performanceReported.setupDefaultFlipperReporter();

const perfModule = require('react-native-performance');
perfModule.setResourceLoggingEnabled(true);
performance = perfModule.default;
rnPerformance = perfModule.default;

// Monitor some native marks that we want to put on the timeline
new perfModule.PerformanceObserver((list, observer) => {
list.getEntries()
.forEach((entry) => {
if (entry.name === 'nativeLaunchEnd') {
performance.measure('nativeLaunch', 'nativeLaunchStart', 'nativeLaunchEnd');
rnPerformance.measure('nativeLaunch', 'nativeLaunchStart', 'nativeLaunchEnd');
}
if (entry.name === 'downloadEnd') {
performance.measure('jsBundleDownload', 'downloadStart', 'downloadEnd');
rnPerformance.measure('jsBundleDownload', 'downloadStart', 'downloadEnd');
}
if (entry.name === 'runJsBundleEnd') {
performance.measure('runJsBundle', 'runJsBundleStart', 'runJsBundleEnd');
rnPerformance.measure('runJsBundle', 'runJsBundleStart', 'runJsBundleEnd');
}

// We don't need to keep the observer past this point
Expand All @@ -85,13 +86,13 @@ if (canCapturePerformanceMetrics()) {
const end = mark.name;
const name = end.replace(/_end$/, '');
const start = `${name}_start`;
performance.measure(name, start, end);
rnPerformance.measure(name, start, end);
}

// Capture any custom measures or metrics below
if (mark.name === `${CONST.TIMING.SIDEBAR_LOADED}_end`) {
performance.measure('TTI', 'nativeLaunchStart', mark.name);
printPerformanceMetrics();
rnPerformance.measure('TTI', 'nativeLaunchStart', mark.name);
Performance.printPerformanceMetrics();
}
} catch (error) {
// Sometimes there might be no start mark recorded and the measure will fail with an error
Expand All @@ -104,12 +105,12 @@ if (canCapturePerformanceMetrics()) {
/**
* Outputs performance stats. We alert these so that they are easy to access in release builds.
*/
printPerformanceMetrics = () => {
Performance.printPerformanceMetrics = () => {
const stats = [
...performance.getEntriesByName('nativeLaunch'),
...performance.getEntriesByName('runJsBundle'),
...performance.getEntriesByName('jsBundleDownload'),
...performance.getEntriesByName('TTI'),
...rnPerformance.getEntriesByName('nativeLaunch'),
...rnPerformance.getEntriesByName('runJsBundle'),
...rnPerformance.getEntriesByName('jsBundleDownload'),
...rnPerformance.getEntriesByName('TTI'),
]
.filter(entry => entry.duration > 0)
.map(entry => `\u2022 ${entry.name}: ${entry.duration.toFixed(1)}ms`);
Expand All @@ -123,7 +124,7 @@ if (canCapturePerformanceMetrics()) {
* @param {Object} [detail]
* @returns {PerformanceMark}
*/
markStart = (name, detail) => performance.mark(`${name}_start`, {detail});
Performance.markStart = (name, detail) => rnPerformance.mark(`${name}_start`, {detail});

/**
* Add an end mark to the performance entries
Expand All @@ -132,7 +133,7 @@ if (canCapturePerformanceMetrics()) {
* @param {Object} [detail]
* @returns {PerformanceMark}
*/
markEnd = (name, detail) => performance.mark(`${name}_end`, {detail});
Performance.markEnd = (name, detail) => rnPerformance.mark(`${name}_end`, {detail});

/**
* Put data emitted by Profiler components on the timeline
Expand All @@ -145,15 +146,15 @@ if (canCapturePerformanceMetrics()) {
* @param {Set} interactions the Set of interactions belonging to this update
* @returns {PerformanceMeasure}
*/
traceRender = (
Performance.traceRender = (
id,
phase,
actualDuration,
baseDuration,
startTime,
commitTime,
interactions,
) => performance.measure(id, {
) => rnPerformance.measure(id, {
start: startTime,
duration: actualDuration,
detail: {
Expand All @@ -170,9 +171,9 @@ if (canCapturePerformanceMetrics()) {
* @param {string} config.id
* @returns {function(React.Component): React.FunctionComponent}
*/
withRenderTrace = ({id}) => (WrappedComponent) => {
Performance.withRenderTrace = ({id}) => (WrappedComponent) => {
const WithRenderTrace = forwardRef((props, ref) => (
<Profiler id={id} onRender={traceRender}>
<Profiler id={id} onRender={Performance.traceRender}>
{/* eslint-disable-next-line react/jsx-props-no-spreading */}
<WrappedComponent {...props} ref={ref} />
</Profiler>
Expand All @@ -183,12 +184,4 @@ if (canCapturePerformanceMetrics()) {
};
}

export {
diffObject,
printPerformanceMetrics,
setupPerformanceObserver,
markStart,
markEnd,
traceRender,
withRenderTrace,
};
export default Performance;
6 changes: 3 additions & 3 deletions src/libs/actions/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import CONST from '../../CONST';
import Log from '../Log';
import CONFIG from '../../CONFIG';
import ROUTES from '../../ROUTES';
import {markEnd, markStart} from '../Performance';
import Performance from '../Performance';
import Timing from './Timing';

let currentUserAccountID;
Expand Down Expand Up @@ -60,8 +60,8 @@ function setSidebarLoaded() {

Onyx.set(ONYXKEYS.IS_SIDEBAR_LOADED, true);
Timing.end(CONST.TIMING.SIDEBAR_LOADED);
markEnd(CONST.TIMING.SIDEBAR_LOADED);
markStart(CONST.TIMING.REPORT_INITIAL_RENDER);
Performance.markEnd(CONST.TIMING.SIDEBAR_LOADED);
Performance.markStart(CONST.TIMING.REPORT_INITIAL_RENDER);
}

let appState;
Expand Down
8 changes: 4 additions & 4 deletions src/pages/home/report/ReportActionsView.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ import {contextMenuRef} from './ContextMenu/ReportActionContextMenu';
import PopoverReportActionContextMenu from './ContextMenu/PopoverReportActionContextMenu';
import variables from '../../../styles/variables';
import MarkerBadge from './MarkerBadge';
import {markEnd, withRenderTrace} from '../../../libs/Performance';
import Performance from '../../../libs/Performance';

const propTypes = {
/** The ID of the report actions will be created for */
Expand Down Expand Up @@ -409,10 +409,10 @@ class ReportActionsView extends React.Component {

// Capture the init measurement only once not per each chat switch as the value gets overwritten
if (!ReportActionsView.initMeasured) {
markEnd(CONST.TIMING.REPORT_INITIAL_RENDER);
Performance.markEnd(CONST.TIMING.REPORT_INITIAL_RENDER);
ReportActionsView.initMeasured = true;
} else {
markEnd(CONST.TIMING.SWITCH_REPORT);
Performance.markEnd(CONST.TIMING.SWITCH_REPORT);
}
}

Expand Down Expand Up @@ -519,7 +519,7 @@ ReportActionsView.propTypes = propTypes;
ReportActionsView.defaultProps = defaultProps;

export default compose(
withRenderTrace({id: '<ReportActionsView> rendering'}),
Performance.withRenderTrace({id: '<ReportActionsView> rendering'}),
withWindowDimensions,
withDrawerState,
withLocalize,
Expand Down
6 changes: 3 additions & 3 deletions src/pages/home/sidebar/SidebarScreen.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import {
import Permissions from '../../../libs/Permissions';
import ONYXKEYS from '../../../ONYXKEYS';
import {create} from '../../../libs/actions/Policy';
import {markStart} from '../../../libs/Performance';
import Performance from '../../../libs/Performance';

const propTypes = {
/** Beta features list */
Expand All @@ -50,7 +50,7 @@ class SidebarScreen extends Component {
}

componentDidMount() {
markStart(CONST.TIMING.SIDEBAR_LOADED);
Performance.markStart(CONST.TIMING.SIDEBAR_LOADED);
Timing.start(CONST.TIMING.SIDEBAR_LOADED, true);
}

Expand Down Expand Up @@ -86,7 +86,7 @@ class SidebarScreen extends Component {
*/
startTimer() {
Timing.start(CONST.TIMING.SWITCH_REPORT);
markStart(CONST.TIMING.SWITCH_REPORT);
Performance.markStart(CONST.TIMING.SWITCH_REPORT);
}

render() {
Expand Down
4 changes: 2 additions & 2 deletions src/setup/index.native.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {setupPerformanceObserver} from '../libs/Performance';
import Performance from '../libs/Performance';

// Setup Flipper plugins when on dev
export default function () {
Expand All @@ -10,5 +10,5 @@ export default function () {
RNAsyncStorageFlipper(AsyncStorage);
}

setupPerformanceObserver();
Performance.setupPerformanceObserver();
}

0 comments on commit 9ea80ba

Please sign in to comment.