Use global or scoped performance loggers everywhere

Summary:
I'm changing all callsites to use either global or scoped perf logger explicitly in one diff.
`GlobalPerformanceLogger` is basically a singleton
`scopedPerformanceLogger` is scoped to the React tree by using a React Context

Reviewed By: sahrens

Differential Revision: D14186694

fbshipit-source-id: 062c76eea8fce9d9b531f0eddf153bb79d52f68d
This commit is contained in:
Alexey Lang
2019-03-06 09:48:41 -08:00
committed by Facebook Github Bot
parent ea8571b0eb
commit a9b3ca7fa7
7 changed files with 92 additions and 10 deletions

View File

@@ -44,12 +44,12 @@ if (__DEV__) {
require('setUpDeveloperTools');
}
const PerformanceLogger = require('GlobalPerformanceLogger');
// We could just call PerformanceLogger.markPoint at the top of the file,
// but then we'd be excluding the time it took to require PerformanceLogger.
const GlobalPerformanceLogger = require('GlobalPerformanceLogger');
// We could just call GlobalPerformanceLogger.markPoint at the top of the file,
// but then we'd be excluding the time it took to require the logger.
// Instead, we just use Date.now and backdate the timestamp.
PerformanceLogger.markPoint(
GlobalPerformanceLogger.markPoint(
'initializeCore_start',
PerformanceLogger.currentTimestamp() - (Date.now() - start),
GlobalPerformanceLogger.currentTimestamp() - (Date.now() - start),
);
PerformanceLogger.markPoint('initializeCore_end');
GlobalPerformanceLogger.markPoint('initializeCore_end');

View File

@@ -30,7 +30,7 @@ BatchedBridge.registerLazyCallableModule('RCTDeviceEventEmitter', () =>
BatchedBridge.registerLazyCallableModule('RCTNativeAppEventEmitter', () =>
require('RCTNativeAppEventEmitter'),
);
BatchedBridge.registerLazyCallableModule('PerformanceLogger', () =>
BatchedBridge.registerLazyCallableModule('GlobalPerformanceLogger', () =>
require('GlobalPerformanceLogger'),
);
BatchedBridge.registerLazyCallableModule('JSDevSupportModule', () =>

View File

@@ -10,15 +10,21 @@
'use strict';
const PerformanceLogger = require('GlobalPerformanceLogger');
const PerformanceLoggerContext = require('PerformanceLoggerContext');
const GlobalPerformanceLogger = require('GlobalPerformanceLogger');
const React = require('React');
const StyleSheet = require('StyleSheet');
const Text = require('Text');
const View = require('View');
class PerformanceOverlay extends React.Component<{}> {
static contextType = PerformanceLoggerContext;
render() {
const perfLogs = PerformanceLogger.getTimespans();
const scopedPerformanceLogger = this.context;
const perfLogs = {
...scopedPerformanceLogger.getTimespans(),
...GlobalPerformanceLogger.getTimespans(),
};
const items = [];
for (const key in perfLogs) {

View File

@@ -11,5 +11,14 @@
const createPerformanceLogger = require('createPerformanceLogger');
/**
* This is a global shared instance of IPerformanceLogger that is created with
* createPerformanceLogger().
* Any metric that you log with this logger will be attached to *all* in-flight
* TTI/TTRC events so you should use it carefully. If you want to log something
* from your React component you should use PerformanceLoggerContext instead.
* This logger should be used only for global stuff like load_bundle events.
*/
const GlobalPerformanceLogger = createPerformanceLogger();
module.exports = GlobalPerformanceLogger;

View File

@@ -14,7 +14,14 @@ import * as React from 'react';
import GlobalPerformanceLogger from 'GlobalPerformanceLogger';
import type {IPerformanceLogger} from 'createPerformanceLogger';
/**
* This is a React Context that provides a scoped instance of IPerformanceLogger.
* We wrap every <AppContainer /> with a Provider for this context so the logger
* should be available everywhere in your components.
* See React docs about using Context: https://reactjs.org/docs/context.html
*/
const PerformanceLoggerContext: React.Context<
IPerformanceLogger,
> = React.createContext(GlobalPerformanceLogger);
export default PerformanceLoggerContext;
module.exports = PerformanceLoggerContext;

View File

@@ -42,6 +42,7 @@ export type IPerformanceLogger = {
markPoint(string, number | void): void,
getPoints(): {[key: string]: number},
logPoints(): void,
logEverything(): void,
};
const _cookies: {[key: string]: number} = {};
@@ -242,6 +243,12 @@ function createPerformanceLogger(): IPerformanceLogger {
infoLog(key + ': ' + this._points[key] + 'ms');
}
},
logEverything() {
this.logTimespans();
this.logExtras();
this.logPoints();
},
};
return result;
}

View File

@@ -0,0 +1,53 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
* @format
*/
'use strict';
const React = require('React');
const PerformanceLoggerContext = require('PerformanceLoggerContext');
import type {IPerformanceLogger} from 'createPerformanceLogger';
export type PerformanceLoggerContextProps = {
scopedPerformanceLogger: IPerformanceLogger,
};
/**
* If you already have one React Context on your component, you can't use
* PerformanceLoggerContext without a consumer for it. This function helps to
* do that. Here's how to use it:
* 1) Intersect Props of your component with PerformanceLoggerContextProps.
* 2) Call this function with Props and RequiredProps of your component.
* You can figure out RequiredProps as $Diff<Props, DefaultProps>.
*/
function withPerformanceLoggerContext<
TProps: PerformanceLoggerContextProps,
TRequiredProps: PerformanceLoggerContextProps,
>(
Component: React.ComponentType<TProps>,
): React.ComponentType<$Diff<TRequiredProps, PerformanceLoggerContextProps>> {
return class WrappedComponent extends React.Component<
$Diff<TProps, PerformanceLoggerContextProps>,
> {
render() {
return (
<PerformanceLoggerContext.Consumer>
{scopedPerformanceLogger => (
<Component
{...this.props}
scopedPerformanceLogger={scopedPerformanceLogger}
/>
)}
</PerformanceLoggerContext.Consumer>
);
}
};
}
module.exports = withPerformanceLoggerContext;