From 9b2396a1f6c16cf38eb7aa9f144c5d926ca9a8a5 Mon Sep 17 00:00:00 2001 From: Mateusz Titz Date: Wed, 10 Jul 2024 16:38:47 +0200 Subject: [PATCH] Improve performance of Search list --- src/components/Search/index.tsx | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/components/Search/index.tsx b/src/components/Search/index.tsx index fc5c23d5c9ec..797d454e48c3 100644 --- a/src/components/Search/index.tsx +++ b/src/components/Search/index.tsx @@ -1,5 +1,6 @@ import {useNavigation} from '@react-navigation/native'; import type {StackNavigationProp} from '@react-navigation/stack'; +import lodashMemoize from 'lodash/memoize'; import React, {useCallback, useEffect, useRef} from 'react'; import type {OnyxEntry} from 'react-native-onyx'; import {useOnyx} from 'react-native-onyx'; @@ -50,6 +51,9 @@ function Search({query, policyIDs, sortBy, sortOrder}: SearchProps) { const lastSearchResultsRef = useRef>(); const {setCurrentSearchHash} = useSearchContext(); + const hash = SearchUtils.getQueryHash(query, policyIDs, sortBy, sortOrder); + const [currentSearchResults, searchResultsMeta] = useOnyx(`${ONYXKEYS.COLLECTION.SNAPSHOT}${hash}`); + const getItemHeight = useCallback( (item: TransactionListItemType | ReportListItemType) => { if (SearchUtils.isTransactionListItemType(item)) { @@ -70,8 +74,15 @@ function Search({query, policyIDs, sortBy, sortOrder}: SearchProps) { [isLargeScreenWidth], ); - const hash = SearchUtils.getQueryHash(query, policyIDs, sortBy, sortOrder); - const [currentSearchResults, searchResultsMeta] = useOnyx(`${ONYXKEYS.COLLECTION.SNAPSHOT}${hash}`); + const getItemHeightMemoized = lodashMemoize( + (item: TransactionListItemType | ReportListItemType) => getItemHeight(item), + (item) => { + // List items are displayed differently on "L"arge and "N"arrow screens so the height will differ + // in addition the same items might be displayed as part of different Search screens ("Expenses", "All", "Finished") + const screenSizeHash = isLargeScreenWidth ? 'L' : 'N'; + return `${hash}-${item.keyForList}-${screenSizeHash}`; + }, + ); // save last non-empty search results to avoid ugly flash of loading screen when hash changes and onyx returns empty data if (currentSearchResults?.data && currentSearchResults !== lastSearchResultsRef.current) { @@ -197,7 +208,7 @@ function Search({query, policyIDs, sortBy, sortOrder}: SearchProps) { updateCellsBatchingPeriod={200} ListItem={ListItem} onSelectRow={openReport} - getItemHeight={getItemHeight} + getItemHeight={getItemHeightMemoized} shouldDebounceRowSelect shouldPreventDefaultFocusOnSelectRow={!DeviceCapabilities.canUseTouchScreen()} listHeaderWrapperStyle={[styles.ph8, styles.pv3, styles.pb5]}