diff --git a/src/CONST.js b/src/CONST.js
index 2d82c601f3cd..9e4707b16a81 100755
--- a/src/CONST.js
+++ b/src/CONST.js
@@ -372,6 +372,7 @@ const CONST = {
SWITCH_REPORT: 'switch_report',
SIDEBAR_LOADED: 'sidebar_loaded',
COLD: 'cold',
+ WARM: 'warm',
REPORT_ACTION_ITEM_LAYOUT_DEBOUNCE_TIME: 1500,
SHOW_LOADING_SPINNER_DEBOUNCE_TIME: 250,
TOOLTIP_SENSE: 1000,
diff --git a/src/libs/Navigation/AppNavigator/MainDrawerNavigator.js b/src/libs/Navigation/AppNavigator/MainDrawerNavigator.js
index ecc67769e8b8..49c2b6093ac3 100644
--- a/src/libs/Navigation/AppNavigator/MainDrawerNavigator.js
+++ b/src/libs/Navigation/AppNavigator/MainDrawerNavigator.js
@@ -2,11 +2,14 @@ import React, {Component} from 'react';
import PropTypes from 'prop-types';
import lodashGet from 'lodash/get';
import {withOnyx} from 'react-native-onyx';
+import _ from 'underscore';
import FullScreenLoadingIndicator from '../../../components/FullscreenLoadingIndicator';
import ONYXKEYS from '../../../ONYXKEYS';
import SCREENS from '../../../SCREENS';
import Permissions from '../../Permissions';
+import Timing from '../../actions/Timing';
+import CONST from '../../../CONST';
// Screens
import ReportScreen from '../../../pages/home/ReportScreen';
@@ -57,7 +60,12 @@ const getInitialReportScreenParams = (reports, ignoreDefaultRooms, policies) =>
class MainDrawerNavigator extends Component {
constructor(props) {
super(props);
+ this.trackAppStartTiming = this.trackAppStartTiming.bind(this);
this.initialParams = getInitialReportScreenParams(props.reports, !Permissions.canUseDefaultRooms(props.betas), props.policies);
+
+ // When we have chat reports the moment this component got created
+ // we know that the data was served from storage/cache
+ this.isFromCache = _.size(props.reports) > 0;
}
shouldComponentUpdate(nextProps) {
@@ -70,6 +78,15 @@ class MainDrawerNavigator extends Component {
return true;
}
+ trackAppStartTiming() {
+ // We only want to report timing events when rendering from cached data
+ if (!this.isFromCache) {
+ return;
+ }
+
+ Timing.end(CONST.TIMING.SIDEBAR_LOADED);
+ }
+
render() {
// Wait until reports are fetched and there is a reportID in initialParams
if (!this.initialParams.reportID) {
@@ -87,6 +104,7 @@ class MainDrawerNavigator extends Component {
return (
);
diff --git a/src/libs/actions/App.js b/src/libs/actions/App.js
index 874b45f1fc57..b405ae82aa49 100644
--- a/src/libs/actions/App.js
+++ b/src/libs/actions/App.js
@@ -9,7 +9,6 @@ import ONYXKEYS from '../../ONYXKEYS';
import CONST from '../../CONST';
import Log from '../Log';
import Performance from '../Performance';
-import Timing from './Timing';
import * as Policy from './Policy';
import Navigation from '../Navigation/Navigation';
import ROUTES from '../../ROUTES';
@@ -95,7 +94,6 @@ function setSidebarLoaded() {
}
Onyx.set(ONYXKEYS.IS_SIDEBAR_LOADED, true);
- Timing.end(CONST.TIMING.SIDEBAR_LOADED);
Performance.markEnd(CONST.TIMING.SIDEBAR_LOADED);
Performance.markStart(CONST.TIMING.REPORT_INITIAL_RENDER);
}
diff --git a/src/libs/actions/Timing.js b/src/libs/actions/Timing.js
index 1c681dfea25e..ab0b72e0e31a 100644
--- a/src/libs/actions/Timing.js
+++ b/src/libs/actions/Timing.js
@@ -32,29 +32,32 @@ function end(eventName, secondaryName = '') {
return;
}
- const {startTime, shouldUseFirebase} = timestampData[eventName];
- const eventTime = Date.now() - startTime;
+ Environment.getEnvironment().then((envName) => {
+ const {startTime, shouldUseFirebase} = timestampData[eventName];
+ const eventTime = Date.now() - startTime;
- if (shouldUseFirebase) {
- Firebase.stopTrace(eventName);
- }
+ if (shouldUseFirebase) {
+ Firebase.stopTrace(eventName);
+ }
- const grafanaEventName = secondaryName
- ? `expensify.cash.${eventName}.${secondaryName}`
- : `expensify.cash.${eventName}`;
+ const baseEventName = `${envName}.new.expensify.${eventName}`;
+ const grafanaEventName = secondaryName
+ ? `${baseEventName}.${secondaryName}`
+ : baseEventName;
- console.debug(`Timing:${grafanaEventName}`, eventTime);
- delete timestampData[eventName];
+ console.debug(`Timing:${grafanaEventName}`, eventTime);
+ delete timestampData[eventName];
- if (Environment.isDevelopment()) {
- // Don't create traces on dev as this will mess up the accuracy of data in release builds of the app
- return;
- }
+ if (Environment.isDevelopment()) {
+ // Don't create traces on dev as this will mess up the accuracy of data in release builds of the app
+ return;
+ }
- API.write('SendPerformanceTiming', {
- name: grafanaEventName,
- value: eventTime,
- platform: `${getPlatform()}`,
+ API.write('SendPerformanceTiming', {
+ name: grafanaEventName,
+ value: eventTime,
+ platform: `${getPlatform()}`,
+ });
});
}
diff --git a/src/pages/home/report/ReportActionsView.js b/src/pages/home/report/ReportActionsView.js
index 9983cc804525..711a0045026b 100755
--- a/src/pages/home/report/ReportActionsView.js
+++ b/src/pages/home/report/ReportActionsView.js
@@ -60,6 +60,7 @@ class ReportActionsView extends React.Component {
this.didLayout = false;
this.didSubscribeToReportTypingEvents = false;
this.unsubscribeVisibilityListener = null;
+ this.hasCachedActions = _.size(props.reportActions) > 0;
// We need this.sortedAndFilteredReportActions to be set before this.state is initialized because the function to calculate the newMarkerReportActionID uses the sorted report actions
this.sortedAndFilteredReportActions = this.getSortedReportActionsForDisplay(props.reportActions);
@@ -348,7 +349,7 @@ class ReportActionsView extends React.Component {
}
this.didLayout = true;
- Timing.end(CONST.TIMING.SWITCH_REPORT, CONST.TIMING.COLD);
+ Timing.end(CONST.TIMING.SWITCH_REPORT, this.hasCachedActions ? CONST.Timing.WARM : CONST.TIMING.COLD);
// Capture the init measurement only once not per each chat switch as the value gets overwritten
if (!ReportActionsView.initMeasured) {
diff --git a/src/pages/home/sidebar/SidebarLinks.js b/src/pages/home/sidebar/SidebarLinks.js
index 09a3f9a21d6a..393662dd12a8 100644
--- a/src/pages/home/sidebar/SidebarLinks.js
+++ b/src/pages/home/sidebar/SidebarLinks.js
@@ -61,6 +61,9 @@ const propTypes = {
/** Current reportID from the route in react navigation state object */
reportIDFromRoute: PropTypes.string,
+ /** Callback when onLayout of sidebar is called */
+ onLayout: PropTypes.func,
+
/** Whether we are viewing below the responsive breakpoint */
isSmallScreenWidth: PropTypes.bool.isRequired,
@@ -78,6 +81,7 @@ const defaultProps = {
avatar: ReportUtils.getDefaultAvatar(),
},
reportIDFromRoute: '',
+ onLayout: () => {},
priorityMode: CONST.PRIORITY_MODE.DEFAULT,
};
@@ -189,6 +193,7 @@ class SidebarLinks extends React.Component {
shouldDisableFocusOptions={this.props.isSmallScreenWidth}
optionMode={this.props.priorityMode === CONST.PRIORITY_MODE.GSD ? 'compact' : 'default'}
onLayout={() => {
+ this.props.onLayout();
App.setSidebarLoaded();
this.isSidebarLoaded = true;
}}
diff --git a/src/pages/home/sidebar/SidebarScreen/BaseSidebarScreen.js b/src/pages/home/sidebar/SidebarScreen/BaseSidebarScreen.js
index 3410b95e4163..bcca70f3f354 100644
--- a/src/pages/home/sidebar/SidebarScreen/BaseSidebarScreen.js
+++ b/src/pages/home/sidebar/SidebarScreen/BaseSidebarScreen.js
@@ -63,6 +63,7 @@ class BaseSidebarScreen extends Component {
isSmallScreenWidth={this.props.isSmallScreenWidth}
isDrawerOpen={this.props.isDrawerOpen}
reportIDFromRoute={this.props.reportIDFromRoute}
+ onLayout={this.props.onLayout}
/>
diff --git a/src/pages/home/sidebar/SidebarScreen/sidebarPropTypes.js b/src/pages/home/sidebar/SidebarScreen/sidebarPropTypes.js
index 3affaa2d00be..ec44cd8de44b 100644
--- a/src/pages/home/sidebar/SidebarScreen/sidebarPropTypes.js
+++ b/src/pages/home/sidebar/SidebarScreen/sidebarPropTypes.js
@@ -4,5 +4,8 @@ const sidebarPropTypes = {
/** reportID in the current navigation state */
reportIDFromRoute: PropTypes.string,
+
+ /** Callback when onLayout of sidebar is called */
+ onLayout: PropTypes.func,
};
export default sidebarPropTypes;