Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[NOQA] fix: performance analytics markers #51815

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
94f9bd2
chore: remove the homepage_initial_render event
adhorodyski Oct 31, 2024
647c3f1
chore: remove the chat_render event
adhorodyski Oct 31, 2024
cb25dc4
chore: remove the report_initial_render event
adhorodyski Oct 31, 2024
67a7ec8
chore: remove the sidebar_loaded event
adhorodyski Oct 31, 2024
fbc01be
chore: remove the switch_report event
adhorodyski Oct 31, 2024
6f0eabb
feat: start remote tracking the message_sent event
adhorodyski Oct 31, 2024
e09796c
feat: start remote tracking the open_report event
adhorodyski Oct 31, 2024
5f27a44
feat: update docs & impl for the open_search event
adhorodyski Nov 4, 2024
c7a661a
docs: update descriptions for the search_filter_options and load_filt…
adhorodyski Nov 4, 2024
c1a0d42
Revert "chore: remove the sidebar_loaded event"
adhorodyski Nov 5, 2024
0d3cf61
fix: imports
adhorodyski Nov 5, 2024
2e7f51a
chore: clear imports linter checks
adhorodyski Nov 5, 2024
8c3da54
chore: rm redundant promise unwrap for removed chat_render
adhorodyski Nov 5, 2024
ee03b3d
fix: linking test for chats
adhorodyski Nov 5, 2024
903f2c4
chore: empty line
adhorodyski Nov 5, 2024
82d58be
feat: do not start the sidebar_loaded event
adhorodyski Nov 5, 2024
b0cc392
chore: rm redundant timing module import
adhorodyski Nov 6, 2024
eb7f2db
fix: linking test assertion scenario
adhorodyski Nov 8, 2024
291dc29
feat: add missing performance markers, rename message_sent to send_me…
adhorodyski Nov 8, 2024
669e3a0
chore: rm redundant timing module import
adhorodyski Nov 8, 2024
216db09
docs: rename message_sent to send_message
adhorodyski Nov 8, 2024
11ff391
fix: sidebar_loaded end event trigger & docs
adhorodyski Nov 12, 2024
41978b1
Merge branch 'Expensify:main' into feat/perf-analytics-markers
adhorodyski Nov 12, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 7 additions & 12 deletions contributingGuides/PERFORMANCE_METRICS.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,16 @@ Project is using Firebase for tracking these metrics. However, not all of them a
| `js_loaded` | ✅ | The time it takes for the JavaScript bundle to load. <br><br>**Platforms:** Android, iOS | **Android:** Starts in the `onCreate` method.<br><br>**iOS:** Starts in the AppDelegate's `didFinishLaunchingWithOptions` method. | Stops at the first render of the app via native module on the JS side. |
| `_app_in_foreground` | ✅ | The time when the app is running in the foreground and available to the user.<br><br>**Platforms:** Android, iOS | **Android:** Starts when the first activity to reach the foreground has its `onResume()` method called. <br><br>**iOS:** Starts when the application receives the `UIApplicationDidBecomeActiveNotification` notification. | **Android:** Stops when the last activity to leave the foreground has its `onStop()` method called. <br><br>**iOS:** Stops when it receives the `UIApplicationWillResignActiveNotification` notification. |
| `_app_in_background` | ✅ | Time when the app is running in the background.<br><br>**Platforms:** Android, iOS | **Android:** Starts when the last activity to leave the foreground has its `onStop()` method called. <br><br>**iOS:** Starts when the application receives the `UIApplicationWillResignActiveNotification` notification. | **Android:** Stops when the first activity to reach the foreground has its `onResume()` method called. <br><br>**iOS:** Stops when it receives the `UIApplicationDidBecomeActiveNotification` notification. |
| `homepage_initial_render` | ✅ | Time taken for the initial render of the app for a logged in user.<br><br>**Platforms:** All | Starts with the first render of the `AuthScreens` component. | Stops once the `AuthScreens` component is mounted. |
| `sidebar_loaded` | ❌ | Time taken for the Sidebar to load.<br><br>**Platforms:** All | Starts when the Sidebar is mounted. | Stops when the Splash Screen is hidden. |
| `sidebar_loaded` | ❌ | Time taken for the Sidebar to load.<br><br>**Platforms:** All | Starts when the Sidebar is mounted. | Stops when the LHN finishes laying out. |
| `calc_most_recent_last_modified_action` | ✅ | Time taken to find the most recently modified report action or report.<br><br>**Platforms:** All | Starts when the app reconnects to the network | Ends when the app reconnects to the network and the most recent report action or report is found. |
| `search_render` | ✅ | Time taken to render the Chat Finder page.<br><br>**Platforms:** All | Starts when the Chat Finder icon in LHN is pressed. | Stops when the list of available options is rendered for the first time. |
| `load_search_options` | ✅ | Time taken to generate the list of options used in Chat Finder.<br><br>**Platforms:** All | Starts when the `getSearchOptions` function is called. | Stops when the list of available options is generated. |
| `search_filter_options` | ✅ | Time taken to filter search options in Chat Finder by given search value.<br><br>**Platforms:** All | Starts when user types something in the Chat Finder search input. | Stops when the list of filtered options is generated. |
| `open_search` | ✅ | Time taken to open up the Search Router.<br><br>**Platforms:** All | Starts when the Search Router icon in LHN is pressed. | Stops when the list of available options finishes laying out. |
| `load_search_options` | ✅ | Time taken to generate the list of options used in the Search Router.<br><br>**Platforms:** All | Starts when the `getSearchOptions` function is called. | Stops when the list of available options is generated. |
| `search_filter_options` | ✅ | Time taken to filter search options in the Search Router by the given search value.<br><br>**Platforms:** All | Starts when user types something in the Search Router search input. | Stops when the list of filtered options is generated. |
| `trie_initialization` | ✅ | Time taken to build the emoji trie.<br><br>**Platforms:** All | Starts when emoji trie begins to build. | Stops when emoji trie building is complete. |
| `open_report` | ❌ | Time taken to open a report.<br><br>**Platforms:** All | Starts when the row in the `LHNOptionsList` is pressed. | Stops when the `ReportActionsList` finishes laying out. |
| `switch_report` | ✅ | Time taken to open report.<br><br>**Platforms:** All | Starts when the chat in the LHN is pressed. | Stops when the `ReportActionsList` finishes laying out. |
| `open_report` | ✅ | Time taken to open a report.<br><br>**Platforms:** All | Starts when the row in the `LHNOptionsList` is pressed. | Stops when the `ReportActionsList` finishes laying out. |
| `open_report_from_preview` | ✅ | Time taken to open a report from preview.<br><br>(previously `switch_report_from_preview`)<br><br>**Platforms:** All | Starts when the user presses the Report Preview. | Stops when the `ReportActionsList` finishes laying out. |
| `switch_report_from_preview` | ❌ | **[REMOVED]** Time taken to open a report from preview. | Starts when the user presses the Report Preview. | Stops when the `ReportActionsList` finishes laying out. |
| `chat_render` | ✅ | Time taken to render the Report screen.<br><br>**Platforms:** All | Starts when the `ReportScreen` is being rendered for the first time. | Stops once the `ReportScreen` component is mounted. |
| `report_initial_render` | ❌ | Time taken to render the Report screen.<br><br>**Platforms:** All | Starts when the first item is rendered in the `LHNOptionsList`. | Stops when the `ReportActionsList` finishes laying out. |
| `open_report_thread` | ✅ | Time taken to open a thread in a report.<br><br>**Platforms:** All | Starts when user presses Report Action Item. | Stops when the `ReportActionsList` finishes laying out. |
| `message_sent` | | Time taken to send a message.<br><br>**Platforms:** All | Starts when the new message is sent. | Stops when the message is being rendered in the chat. |
| `send_message` | | Time taken to send a message.<br><br>**Platforms:** All | Starts when the new message is sent. | Stops when the message is being rendered in the chat. |

## Documentation Maintenance

Expand All @@ -46,4 +41,4 @@ To ensure this documentation remains accurate and useful, please adhere to the f
## Additional Resources

- [Firebase Documentation](https://firebase.google.com/docs)
- [Firebase Performance Monitoring](https://firebase.google.com/docs/perf-mon)
- [Firebase Performance Monitoring](https://firebase.google.com/docs/perf-mon)
8 changes: 2 additions & 6 deletions src/CONST.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1254,17 +1254,13 @@ const CONST = {
},
TIMING: {
CALCULATE_MOST_RECENT_LAST_MODIFIED_ACTION: 'calc_most_recent_last_modified_action',
SEARCH_ROUTER_RENDER: 'search_router_render',
CHAT_RENDER: 'chat_render',
OPEN_SEARCH: 'open_search',
OPEN_REPORT: 'open_report',
HOMEPAGE_INITIAL_RENDER: 'homepage_initial_render',
REPORT_INITIAL_RENDER: 'report_initial_render',
SWITCH_REPORT: 'switch_report',
OPEN_REPORT_FROM_PREVIEW: 'open_report_from_preview',
OPEN_REPORT_THREAD: 'open_report_thread',
SIDEBAR_LOADED: 'sidebar_loaded',
LOAD_SEARCH_OPTIONS: 'load_search_options',
MESSAGE_SENT: 'message_sent',
SEND_MESSAGE: 'send_message',
COLD: 'cold',
WARM: 'warm',
REPORT_ACTION_ITEM_LAYOUT_DEBOUNCE_TIME: 1500,
Expand Down
2 changes: 0 additions & 2 deletions src/Expensify.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ import NavigationRoot from './libs/Navigation/NavigationRoot';
import NetworkConnection from './libs/NetworkConnection';
import PushNotification from './libs/Notification/PushNotification';
import './libs/Notification/PushNotification/subscribePushNotification';
import Performance from './libs/Performance';
import setCrashlyticsUserId from './libs/setCrashlyticsUserId';
import StartupTimer from './libs/StartupTimer';
// This lib needs to be imported, but it has nothing to export since all it contains is an Onyx connection
Expand Down Expand Up @@ -138,7 +137,6 @@ function Expensify() {

const onSplashHide = useCallback(() => {
setSplashScreenState(CONST.BOOT_SPLASH_STATE.HIDDEN);
Performance.markEnd(CONST.TIMING.SIDEBAR_LOADED);
}, [setSplashScreenState]);

useLayoutEffect(() => {
Expand Down
2 changes: 2 additions & 0 deletions src/components/LHNOptionsList/OptionRowLHN.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import * as ReportUtils from '@libs/ReportUtils';
import * as ReportActionContextMenu from '@pages/home/report/ContextMenu/ReportActionContextMenu';
import FreeTrial from '@pages/settings/Subscription/FreeTrial';
import variables from '@styles/variables';
import Timing from '@userActions/Timing';
import * as User from '@userActions/User';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
Expand Down Expand Up @@ -193,6 +194,7 @@ function OptionRowLHN({reportID, isFocused = false, onSelectRow = () => {}, opti
ref={popoverAnchor}
onPress={(event) => {
Performance.markStart(CONST.TIMING.OPEN_REPORT);
Timing.start(CONST.TIMING.OPEN_REPORT);

event?.preventDefault();
// Enable Composer to focus on clicking the same chat after opening the context menu.
Expand Down
2 changes: 2 additions & 0 deletions src/components/ReportActionItem/ReportPreview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import * as CurrencyUtils from '@libs/CurrencyUtils';
import * as DeviceCapabilities from '@libs/DeviceCapabilities';
import HapticFeedback from '@libs/HapticFeedback';
import Navigation from '@libs/Navigation/Navigation';
import Performance from '@libs/Performance';
import * as PolicyUtils from '@libs/PolicyUtils';
import * as ReceiptUtils from '@libs/ReceiptUtils';
import * as ReportActionsUtils from '@libs/ReportActionsUtils';
Expand Down Expand Up @@ -456,6 +457,7 @@ function ReportPreview({
<View style={[styles.chatItemMessage, containerStyles]}>
<PressableWithoutFeedback
onPress={() => {
Performance.markStart(CONST.TIMING.OPEN_REPORT_FROM_PREVIEW);
Timing.start(CONST.TIMING.OPEN_REPORT_FROM_PREVIEW);
Navigation.navigate(ROUTES.REPORT_WITH_ID.getRoute(iouReportID));
}}
Expand Down
4 changes: 2 additions & 2 deletions src/components/Search/SearchRouter/SearchButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ function SearchButton({style}: SearchButtonProps) {
accessibilityLabel={translate('common.search')}
style={[styles.flexRow, styles.touchableButtonImage, style]}
onPress={Session.checkIfActionIsAllowed(() => {
Timing.start(CONST.TIMING.SEARCH_ROUTER_RENDER);
Performance.markStart(CONST.TIMING.SEARCH_ROUTER_RENDER);
Timing.start(CONST.TIMING.OPEN_SEARCH);
Performance.markStart(CONST.TIMING.OPEN_SEARCH);

openSearchRouter();
})}
Expand Down
4 changes: 2 additions & 2 deletions src/components/Search/SearchRouter/SearchRouterList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,8 @@ type SearchRouterListProps = {
};

const setPerformanceTimersEnd = () => {
Timing.end(CONST.TIMING.SEARCH_ROUTER_RENDER);
Performance.markEnd(CONST.TIMING.SEARCH_ROUTER_RENDER);
Timing.end(CONST.TIMING.OPEN_SEARCH);
Performance.markEnd(CONST.TIMING.OPEN_SEARCH);
};

function getContextualSearchQuery(reportName: string) {
Expand Down
19 changes: 1 addition & 18 deletions src/libs/E2E/tests/chatOpeningTest.e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,9 @@ const test = (config: NativeConfig) => {

console.debug('[E2E] Logged in, getting chat opening metrics and submitting them…');

const [renderChatPromise, renderChatResolve] = getPromiseWithResolve();
const [chatTTIPromise, chatTTIResolve] = getPromiseWithResolve();

Promise.all([renderChatPromise, chatTTIPromise]).then(() => {
chatTTIPromise.then(() => {
console.debug(`[E2E] Submitting!`);

E2EClient.submitTestDone();
Expand All @@ -46,22 +45,6 @@ const test = (config: NativeConfig) => {

console.debug(`[E2E] Entry: ${JSON.stringify(entry)}`);

if (entry.name === CONST.TIMING.CHAT_RENDER) {
E2EClient.submitTestResults({
adhorodyski marked this conversation as resolved.
Show resolved Hide resolved
branch: Config.E2E_BRANCH,
name: `${name} Chat opening`,
metric: entry.duration,
unit: 'ms',
})
.then(() => {
console.debug('[E2E] Done with chat opening, exiting…');
renderChatResolve();
})
.catch((err) => {
console.debug('[E2E] Error while submitting test results:', err);
});
}

if (entry.name === CONST.TIMING.OPEN_REPORT) {
E2EClient.submitTestResults({
branch: Config.E2E_BRANCH,
Expand Down
23 changes: 8 additions & 15 deletions src/libs/E2E/tests/linkingTest.e2e.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import {DeviceEventEmitter} from 'react-native';
import type {NativeConfig} from 'react-native-config';
import Config from 'react-native-config';
import Timing from '@libs/actions/Timing';
import type {NativeConfig} from 'react-native-config';
import E2ELogin from '@libs/E2E/actions/e2eLogin';
import waitForAppLoaded from '@libs/E2E/actions/waitForAppLoaded';
import E2EClient from '@libs/E2E/client';
Expand Down Expand Up @@ -32,9 +31,9 @@ const test = (config: NativeConfig) => {
}

const [appearMessagePromise, appearMessageResolve] = getPromiseWithResolve();
const [switchReportPromise, switchReportResolve] = getPromiseWithResolve();
const [openReportPromise, openReportResolve] = getPromiseWithResolve();

Promise.all([appearMessagePromise, switchReportPromise])
Promise.all([appearMessagePromise, openReportPromise])
.then(() => {
console.debug('[E2E] Test completed successfully, exiting…');
E2EClient.submitTestDone();
Expand All @@ -57,21 +56,15 @@ const test = (config: NativeConfig) => {
Performance.subscribeToMeasurements((entry) => {
if (entry.name === CONST.TIMING.SIDEBAR_LOADED) {
console.debug('[E2E] Sidebar loaded, navigating to a report…');
Performance.markStart(CONST.TIMING.OPEN_REPORT);
Navigation.navigate(ROUTES.REPORT_WITH_ID.getRoute(reportID));
return;
}

if (entry.name === CONST.TIMING.REPORT_INITIAL_RENDER) {
adhorodyski marked this conversation as resolved.
Show resolved Hide resolved
console.debug('[E2E] Navigating to linked report action…');
Timing.start(CONST.TIMING.SWITCH_REPORT);
Performance.markStart(CONST.TIMING.SWITCH_REPORT);
adhorodyski marked this conversation as resolved.
Show resolved Hide resolved

Navigation.navigate(ROUTES.REPORT_WITH_ID.getRoute(linkedReportID, linkedReportActionID));
adhorodyski marked this conversation as resolved.
Show resolved Hide resolved
return;
}

if (entry.name === CONST.TIMING.SWITCH_REPORT) {
if (entry.name === CONST.TIMING.OPEN_REPORT) {
console.debug('[E2E] Linking: 1');
console.debug('[E2E] Navigating to the linked report action…');
Navigation.navigate(ROUTES.REPORT_WITH_ID.getRoute(linkedReportID, linkedReportActionID));

E2EClient.submitTestResults({
branch: Config.E2E_BRANCH,
Expand All @@ -80,7 +73,7 @@ const test = (config: NativeConfig) => {
unit: 'ms',
});

switchReportResolve();
openReportResolve();
}
});
});
Expand Down
2 changes: 1 addition & 1 deletion src/libs/E2E/tests/openSearchRouterTest.e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ const test = (config: NativeConfig) => {
props.onPress();
}

if (entry.name === CONST.TIMING.SEARCH_ROUTER_RENDER) {
if (entry.name === CONST.TIMING.OPEN_SEARCH) {
E2EClient.submitTestResults({
branch: Config.E2E_BRANCH,
name: `${name} Open Search Router TTI`,
Expand Down
2 changes: 1 addition & 1 deletion src/libs/E2E/tests/reportTypingTest.e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ const test = (config: NativeConfig) => {
});

Performance.subscribeToMeasurements((entry) => {
if (entry.name === CONST.TIMING.MESSAGE_SENT) {
if (entry.name === CONST.TIMING.SEND_MESSAGE) {
E2EClient.submitTestResults({
branch: Config.E2E_BRANCH,
name: `${name} Message sent`,
Expand Down
5 changes: 0 additions & 5 deletions src/libs/Navigation/AppNavigator/AuthScreens.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ import * as PriorityMode from '@userActions/PriorityMode';
import * as Report from '@userActions/Report';
import * as Session from '@userActions/Session';
import toggleTestToolsModal from '@userActions/TestTool';
import Timing from '@userActions/Timing';
import * as User from '@userActions/User';
import CONFIG from '@src/CONFIG';
import CONST from '@src/CONST';
Expand Down Expand Up @@ -248,8 +247,6 @@ function AuthScreens({session, lastOpenedPublicRoomID, initialLastUpdateIDApplie

// eslint-disable-next-line react-compiler/react-compiler
if (isInitialRender.current) {
Timing.start(CONST.TIMING.HOMEPAGE_INITIAL_RENDER);

const currentURL = getCurrentUrl();
if (currentURL) {
initialReportID = new URL(currentURL).pathname.match(CONST.REGEX.REPORT_ID_FROM_PATH)?.at(1);
Expand Down Expand Up @@ -313,8 +310,6 @@ function AuthScreens({session, lastOpenedPublicRoomID, initialLastUpdateIDApplie
}
Download.clearDownloads();

Timing.end(CONST.TIMING.HOMEPAGE_INITIAL_RENDER);

const unsubscribeOnyxModal = onyxSubscribe({
key: ONYXKEYS.MODAL,
callback: (modalArg) => {
Expand Down
2 changes: 1 addition & 1 deletion src/libs/actions/App.ts
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ function setSidebarLoaded() {
}

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

let appState: AppStateStatus;
Expand Down
11 changes: 1 addition & 10 deletions src/pages/home/ReportScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,9 @@ import usePrevious from '@hooks/usePrevious';
import useResponsiveLayout from '@hooks/useResponsiveLayout';
import useThemeStyles from '@hooks/useThemeStyles';
import useViewportOffsetTop from '@hooks/useViewportOffsetTop';
import Timing from '@libs/actions/Timing';
import Log from '@libs/Log';
import Navigation from '@libs/Navigation/Navigation';
import clearReportNotifications from '@libs/Notification/clearReportNotifications';
import Performance from '@libs/Performance';
import * as PersonalDetailsUtils from '@libs/PersonalDetailsUtils';
import * as ReportActionsUtils from '@libs/ReportActionsUtils';
import * as ReportUtils from '@libs/ReportUtils';
Expand Down Expand Up @@ -230,11 +228,7 @@ function ReportScreen({route, currentReportID = '', navigation}: ReportScreenPro
const [scrollPosition, setScrollPosition] = useState<ScrollPosition>({});

const wasReportAccessibleRef = useRef(false);
// eslint-disable-next-line react-compiler/react-compiler
if (firstRenderRef.current) {
Timing.start(CONST.TIMING.CHAT_RENDER);
Performance.markStart(CONST.TIMING.CHAT_RENDER);
}

const [isComposerFocus, setIsComposerFocus] = useState(false);
const shouldAdjustScrollView = useMemo(() => isComposerFocus && !modal?.willAlertModalBecomeVisible, [isComposerFocus, modal]);
const viewportOffsetTop = useViewportOffsetTop(shouldAdjustScrollView);
Expand Down Expand Up @@ -487,9 +481,6 @@ function ReportScreen({route, currentReportID = '', navigation}: ReportScreenPro
useAppFocusEvent(clearNotifications);

useEffect(() => {
Timing.end(CONST.TIMING.CHAT_RENDER);
Performance.markEnd(CONST.TIMING.CHAT_RENDER);

const interactionTask = InteractionManager.runAfterInteractions(() => {
ComposerActions.setShouldShowComposeInput(true);
});
Expand Down
Loading
Loading