Skip to content

Commit 1a2d167

Browse files
authored
Merge pull request #91848 from software-mansion-labs/dariusz-biela/perf/search/navigation-deferred-mount
Perf: Defer Search/Reports list mount via NavigationDeferredMount
2 parents b8b82fa + b1afdea commit 1a2d167

3 files changed

Lines changed: 53 additions & 3 deletions

File tree

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import type {ComponentProps} from 'react';
2+
import React from 'react';
3+
import NavigationDeferredMount from '@components/NavigationDeferredMount';
4+
import SearchRowSkeleton from '@components/Skeletons/SearchRowSkeleton';
5+
import useResponsiveLayout from '@hooks/useResponsiveLayout';
6+
import useThemeStyles from '@hooks/useThemeStyles';
7+
import {endSpanWithAttributes} from '@libs/telemetry/activeSpans';
8+
import {endSubmitFollowUpActionSpan, getPendingSubmitFollowUpAction} from '@libs/telemetry/submitFollowUpAction';
9+
import CONST from '@src/CONST';
10+
import Search from './index';
11+
12+
const REASON_ATTRIBUTES = {context: 'SearchPage.NavigationDeferred'} as const;
13+
14+
function handleSkeletonLayout() {
15+
endSpanWithAttributes(CONST.TELEMETRY.SPAN_NAVIGATE_TO_REPORTS, {[CONST.TELEMETRY.ATTRIBUTE_IS_WARM]: true});
16+
17+
// Skeleton paint is the first user-perceivable signal that the submit destination
18+
// (Search) is up. End the submit-to-destination-visible span here for any pending
19+
// action that targets Search. DISMISS_MODAL_AND_OPEN_REPORT is excluded because
20+
// that flow's destination is the report, not Search.
21+
const pending = getPendingSubmitFollowUpAction();
22+
if (pending && pending.followUpAction !== CONST.TELEMETRY.SUBMIT_FOLLOW_UP_ACTION.DISMISS_MODAL_AND_OPEN_REPORT) {
23+
endSubmitFollowUpActionSpan(pending.followUpAction, undefined, {[CONST.TELEMETRY.ATTRIBUTE_IS_WARM]: true});
24+
}
25+
}
26+
27+
function SearchWithNavigationDeferredMount(props: ComponentProps<typeof Search>) {
28+
const styles = useThemeStyles();
29+
const {shouldUseNarrowLayout} = useResponsiveLayout();
30+
const containerStyle = shouldUseNarrowLayout ? styles.searchListContentContainerStyles(!!props.hasFilterBars) : styles.mt3;
31+
32+
return (
33+
<NavigationDeferredMount
34+
waitForUpcomingTransition={false}
35+
placeholder={
36+
<SearchRowSkeleton
37+
shouldAnimate
38+
onLayout={handleSkeletonLayout}
39+
containerStyle={containerStyle}
40+
reasonAttributes={REASON_ATTRIBUTES}
41+
/>
42+
}
43+
>
44+
<Search {...props} />
45+
</NavigationDeferredMount>
46+
);
47+
}
48+
49+
export default SearchWithNavigationDeferredMount;

src/pages/Search/SearchPageNarrow/index.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import {useSearchResultsContext, useSearchSelectionActions} from '@components/Se
1717
import SearchLoadingSkeleton from '@components/Search/SearchLoadingSkeleton';
1818
import SearchPageFooter from '@components/Search/SearchPageFooter';
1919
import SearchPageHeaderNarrow from '@components/Search/SearchPageHeader/SearchPageHeaderNarrow';
20+
import SearchWithNavigationDeferredMount from '@components/Search/SearchWithNavigationDeferredMount';
2021
import type {SearchParams, SearchQueryJSON} from '@components/Search/types';
2122
import useAndroidBackButtonHandler from '@hooks/useAndroidBackButtonHandler';
2223
import useEndSubmitNavigationSpans from '@hooks/useEndSubmitNavigationSpans';
@@ -398,7 +399,7 @@ function SearchPageNarrow({
398399
}}
399400
/>
400401
) : (
401-
<Search
402+
<SearchWithNavigationDeferredMount
402403
searchResults={searchResults}
403404
queryJSON={queryJSON}
404405
key={queryJSON.hash}

src/pages/Search/SearchPageWide.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@ import FullPageNotFoundView from '@components/BlockingViews/FullPageNotFoundView
66
import ReceiptScanDropZone from '@components/ReceiptScanDropZone';
77
import ScreenWrapper from '@components/ScreenWrapper';
88
import {ScrollOffsetContext} from '@components/ScrollOffsetContextProvider';
9-
import Search from '@components/Search';
109
import {useSearchResultsContext} from '@components/Search/SearchContext';
1110
import SearchLoadingSkeleton from '@components/Search/SearchLoadingSkeleton';
1211
import SearchPageFooter from '@components/Search/SearchPageFooter';
1312
import SearchActionsBarWide from '@components/Search/SearchPageHeader/SearchActionsBarWide';
1413
import SearchPageHeaderWide from '@components/Search/SearchPageHeader/SearchPageHeaderWide';
14+
import SearchWithNavigationDeferredMount from '@components/Search/SearchWithNavigationDeferredMount';
1515
import type {SearchParams, SearchQueryJSON} from '@components/Search/types';
1616
import useEndSubmitNavigationSpans from '@hooks/useEndSubmitNavigationSpans';
1717
import useNetwork from '@hooks/useNetwork';
@@ -131,7 +131,7 @@ function SearchPageWide({
131131
}}
132132
/>
133133
) : (
134-
<Search
134+
<SearchWithNavigationDeferredMount
135135
key={queryJSON.hash}
136136
queryJSON={queryJSON}
137137
searchResults={searchResults}

0 commit comments

Comments
 (0)