From 4134d241808f56021d2a4130fb2e3fef69222b5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20Le=C5=9Bniewski?= Date: Tue, 13 Jan 2026 14:06:58 +0100 Subject: [PATCH 1/4] adds a metric with effective render time of Reports tab --- src/CONST/index.ts | 1 + src/components/Search/index.tsx | 24 +++++++++++++++++++++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/CONST/index.ts b/src/CONST/index.ts index 95072e08e2cb1..11366f100bfde 100755 --- a/src/CONST/index.ts +++ b/src/CONST/index.ts @@ -1699,6 +1699,7 @@ const CONST = { SPAN_OPEN_REPORT: 'ManualOpenReport', SPAN_APP_STARTUP: 'ManualAppStartup', SPAN_NAVIGATE_TO_REPORTS_TAB: 'ManualNavigateToReportsTab', + SPAN_NAVIGATE_TO_REPORTS_TAB_RENDER: 'ManualNavigateToReportsTabRender', SPAN_ON_LAYOUT_SKELETON_REPORTS: 'ManualOnLayoutSkeletonReports', SPAN_NAVIGATE_TO_INBOX_TAB: 'ManualNavigateToInboxTab', SPAN_OD_ND_TRANSITION: 'ManualOdNdTransition', diff --git a/src/components/Search/index.tsx b/src/components/Search/index.tsx index 7c7079717c6ed..06649c1d7394c 100644 --- a/src/components/Search/index.tsx +++ b/src/components/Search/index.tsx @@ -56,7 +56,7 @@ import { shouldShowEmptyState, shouldShowYear as shouldShowYearUtil, } from '@libs/SearchUIUtils'; -import {cancelSpan, endSpan, startSpan} from '@libs/telemetry/activeSpans'; +import {cancelSpan, endSpan, getSpan, startSpan} from '@libs/telemetry/activeSpans'; import {getOriginalTransactionWithSplitInfo, isOnHold, isTransactionPendingDelete, mergeProhibitedViolations, shouldShowViolation} from '@libs/TransactionUtils'; import Navigation, {navigationRef} from '@navigation/Navigation'; import type {SearchFullscreenNavigatorParamList} from '@navigation/types'; @@ -947,9 +947,28 @@ function Search({ const onLayout = useCallback(() => { endSpan(CONST.TELEMETRY.SPAN_NAVIGATE_TO_REPORTS_TAB); + endSpan(CONST.TELEMETRY.SPAN_NAVIGATE_TO_REPORTS_TAB_RENDER); handleSelectionListScroll(sortedData, searchListRef.current); }, [handleSelectionListScroll, sortedData]); + useEffect(() => { + if (shouldShowLoadingState) { + return; + } + + const renderSpanParent = getSpan(CONST.TELEMETRY.SPAN_NAVIGATE_TO_REPORTS_TAB); + + if (renderSpanParent) { + startSpan(CONST.TELEMETRY.SPAN_NAVIGATE_TO_REPORTS_TAB_RENDER, { + name: CONST.TELEMETRY.SPAN_NAVIGATE_TO_REPORTS_TAB_RENDER, + op: CONST.TELEMETRY.SPAN_NAVIGATE_TO_REPORTS_TAB_RENDER, + parentSpan: renderSpanParent, + }).setAttributes({ + inputQuery: queryJSON?.inputQuery, + }); + } + }, [shouldShowLoadingState]); + const onLayoutSkeleton = useCallback(() => { endSpan(CONST.TELEMETRY.SPAN_ON_LAYOUT_SKELETON_REPORTS); }, []); @@ -973,12 +992,14 @@ function Search({ if (searchResults === undefined) { Log.alert('[Search] Undefined search type'); cancelSpan(CONST.TELEMETRY.SPAN_NAVIGATE_TO_REPORTS_TAB); + cancelSpan(CONST.TELEMETRY.SPAN_NAVIGATE_TO_REPORTS_TAB_RENDER); return {null}; } if (hasErrors) { const isInvalidQuery = searchRequestResponseStatusCode === CONST.JSON_CODE.INVALID_SEARCH_QUERY; cancelSpan(CONST.TELEMETRY.SPAN_NAVIGATE_TO_REPORTS_TAB); + cancelSpan(CONST.TELEMETRY.SPAN_NAVIGATE_TO_REPORTS_TAB_RENDER); return ( item.pendingAction !== CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE || isOffline).length; if (shouldShowEmptyState(isDataLoaded, visibleDataLength, searchResults?.search?.type)) { cancelSpan(CONST.TELEMETRY.SPAN_NAVIGATE_TO_REPORTS_TAB); + cancelSpan(CONST.TELEMETRY.SPAN_NAVIGATE_TO_REPORTS_TAB_RENDER); return ( Date: Tue, 13 Jan 2026 14:43:30 +0100 Subject: [PATCH 2/4] adds parentSpan to `ManualOnLayoutSkeletonReports` --- src/components/Navigation/NavigationTabBar/index.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/Navigation/NavigationTabBar/index.tsx b/src/components/Navigation/NavigationTabBar/index.tsx index 4635dab48b9e1..2146609a1ac02 100644 --- a/src/components/Navigation/NavigationTabBar/index.tsx +++ b/src/components/Navigation/NavigationTabBar/index.tsx @@ -173,7 +173,7 @@ function NavigationTabBar({selectedTab, isTopLevelBar = false, shouldShowFloatin } clearSelectedText(); interceptAnonymousUser(() => { - startSpan(CONST.TELEMETRY.SPAN_NAVIGATE_TO_REPORTS_TAB, { + const parentSpan = startSpan(CONST.TELEMETRY.SPAN_NAVIGATE_TO_REPORTS_TAB, { name: CONST.TELEMETRY.SPAN_NAVIGATE_TO_REPORTS_TAB, op: CONST.TELEMETRY.SPAN_NAVIGATE_TO_REPORTS_TAB, }); @@ -181,6 +181,7 @@ function NavigationTabBar({selectedTab, isTopLevelBar = false, shouldShowFloatin startSpan(CONST.TELEMETRY.SPAN_ON_LAYOUT_SKELETON_REPORTS, { name: CONST.TELEMETRY.SPAN_ON_LAYOUT_SKELETON_REPORTS, op: CONST.TELEMETRY.SPAN_ON_LAYOUT_SKELETON_REPORTS, + parentSpan, }); const rootState = navigationRef.getRootState() as State; From be83dbf41341db578cd2be5f1947501cd5ef899c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20Le=C5=9Bniewski?= Date: Thu, 15 Jan 2026 12:53:46 +0100 Subject: [PATCH 3/4] remove redundant cancelSpan(), add comments --- src/components/Search/index.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/Search/index.tsx b/src/components/Search/index.tsx index 1f1bfc972ab42..ff84c8db1920d 100644 --- a/src/components/Search/index.tsx +++ b/src/components/Search/index.tsx @@ -979,6 +979,9 @@ function Search({ inputQuery: queryJSON?.inputQuery, }); } + + // Exclude `queryJSON?.inputQuery` since it’s only telemetry metadata and would cause the span to start multiple times. + // eslint-disable-next-line react-hooks/exhaustive-deps }, [shouldShowLoadingState]); const onLayoutSkeleton = useCallback(() => { @@ -1004,14 +1007,12 @@ function Search({ if (searchResults === undefined) { Log.alert('[Search] Undefined search type'); cancelSpan(CONST.TELEMETRY.SPAN_NAVIGATE_TO_REPORTS_TAB); - cancelSpan(CONST.TELEMETRY.SPAN_NAVIGATE_TO_REPORTS_TAB_RENDER); return {null}; } if (hasErrors) { const isInvalidQuery = searchRequestResponseStatusCode === CONST.JSON_CODE.INVALID_SEARCH_QUERY; cancelSpan(CONST.TELEMETRY.SPAN_NAVIGATE_TO_REPORTS_TAB); - cancelSpan(CONST.TELEMETRY.SPAN_NAVIGATE_TO_REPORTS_TAB_RENDER); return ( item.pendingAction !== CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE || isOffline).length; if (shouldShowEmptyState(isDataLoaded, visibleDataLength, searchResults?.search?.type)) { cancelSpan(CONST.TELEMETRY.SPAN_NAVIGATE_TO_REPORTS_TAB); - cancelSpan(CONST.TELEMETRY.SPAN_NAVIGATE_TO_REPORTS_TAB_RENDER); return ( Date: Thu, 15 Jan 2026 13:03:46 +0100 Subject: [PATCH 4/4] fixed prettier --- src/components/Search/index.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/Search/index.tsx b/src/components/Search/index.tsx index 1e40d51e19204..eeed9b8dfbae3 100644 --- a/src/components/Search/index.tsx +++ b/src/components/Search/index.tsx @@ -946,8 +946,8 @@ function Search({ }); } - // Exclude `queryJSON?.inputQuery` since it’s only telemetry metadata and would cause the span to start multiple times. - // eslint-disable-next-line react-hooks/exhaustive-deps + // Exclude `queryJSON?.inputQuery` since it’s only telemetry metadata and would cause the span to start multiple times. + // eslint-disable-next-line react-hooks/exhaustive-deps }, [shouldShowLoadingState]); const onLayoutSkeleton = useCallback(() => {