From 7d158f82fb1c82101c3a0cb637f911ac87e8006b Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 6 Dec 2023 17:50:06 +0000 Subject: [PATCH] Optimize Drawer re-renders (#2108) --- src/view/shell/Drawer.tsx | 496 +++++++++++++++++++------------ src/view/shell/NavSignupCard.tsx | 4 +- 2 files changed, 315 insertions(+), 185 deletions(-) diff --git a/src/view/shell/Drawer.tsx b/src/view/shell/Drawer.tsx index 459a021c..29592cd8 100644 --- a/src/view/shell/Drawer.tsx +++ b/src/view/shell/Drawer.tsx @@ -55,13 +55,13 @@ import {RQKEY as NOTIFS_RQKEY} from '#/state/queries/notifications/feed' import {NavSignupCard} from '#/view/shell/NavSignupCard' import {truncateAndInvalidate} from '#/state/queries/util' -export function DrawerProfileCard({ +let DrawerProfileCard = ({ account, onPressProfile, }: { account: SessionAccount onPressProfile: () => void -}) { +}): React.ReactNode => { const {_} = useLingui() const pal = usePalette('default') const {data: profile} = useProfileQuery({did: account.did}) @@ -103,11 +103,12 @@ export function DrawerProfileCard({ ) } +DrawerProfileCard = React.memo(DrawerProfileCard) +export {DrawerProfileCard} -export function DrawerContent() { +let DrawerContent = ({}: {}): React.ReactNode => { const theme = useTheme() const pal = usePalette('default') - const {_} = useLingui() const queryClient = useQueryClient() const setDrawerOpen = useSetDrawerOpen() const navigation = useNavigation() @@ -115,7 +116,6 @@ export function DrawerContent() { const {isAtHome, isAtSearch, isAtFeeds, isAtNotifications, isAtMyProfile} = useNavigationTabState() const {hasSession, currentAccount} = useSession() - const numUnreadNotifications = useUnreadNotifications() // events // = @@ -229,158 +229,26 @@ export function DrawerContent() { )} - {hasSession && } - + {hasSession && } {hasSession && } - - } - size={24} - strokeWidth={1.7} - /> - ) : ( - } - size={24} - strokeWidth={1.7} - /> - ) - } - label={_(msg`Search`)} - accessibilityLabel={_(msg`Search`)} - accessibilityHint="" - bold={isAtSearch} - onPress={onPressSearch} - /> - } - size="24" - strokeWidth={3.25} - /> - ) : ( - } - size="24" - strokeWidth={3.25} - /> - ) - } - label={_(msg`Home`)} - accessibilityLabel={_(msg`Home`)} - accessibilityHint="" - bold={isAtHome} - onPress={onPressHome} - /> - + + {hasSession && ( - } - size="24" - strokeWidth={1.7} - /> - ) : ( - } - size="24" - strokeWidth={1.7} - /> - ) - } - label={_(msg`Notifications`)} - accessibilityLabel={_(msg`Notifications`)} - accessibilityHint={ - numUnreadNotifications === '' - ? '' - : `${numUnreadNotifications} unread` - } - count={numUnreadNotifications} - bold={isAtNotifications} + )} - - - ) : ( - - ) - } - label={_(msg`Feeds`)} - accessibilityLabel={_(msg`Feeds`)} - accessibilityHint="" - bold={isAtFeeds} - onPress={onPressMyFeeds} - /> - + {hasSession && ( <> - } - label={_(msg`Lists`)} - accessibilityLabel={_(msg`Lists`)} - accessibilityHint="" - onPress={onPressLists} - /> - } - label={_(msg`Moderation`)} - accessibilityLabel={_(msg`Moderation`)} - accessibilityHint="" - onPress={onPressModeration} - /> - } - size="26" - strokeWidth={1.5} - /> - ) : ( - } - size="26" - strokeWidth={1.5} - /> - ) - } - label={_(msg`Profile`)} - accessibilityLabel={_(msg`Profile`)} - accessibilityHint="" + + + - } - size="26" - strokeWidth={1.75} - /> - } - label={_(msg`Settings`)} - accessibilityLabel={_(msg`Settings`)} - accessibilityHint="" - onPress={onPressSettings} - /> + )} @@ -388,43 +256,64 @@ export function DrawerContent() { - - - - - Feedback - - - - - Help - - - + ) } +DrawerContent = React.memo(DrawerContent) +export {DrawerContent} + +let DrawerFooter = ({ + onPressFeedback, + onPressHelp, +}: { + onPressFeedback: () => void + onPressHelp: () => void +}): React.ReactNode => { + const theme = useTheme() + const pal = usePalette('default') + const {_} = useLingui() + return ( + + + + + Feedback + + + + + Help + + + + ) +} +DrawerFooter = React.memo(DrawerFooter) interface MenuItemProps extends ComponentProps { icon: JSX.Element @@ -433,6 +322,244 @@ interface MenuItemProps extends ComponentProps { bold?: boolean } +let SearchMenuItem = ({ + isActive, + onPress, +}: { + isActive: boolean + onPress: () => void +}): React.ReactNode => { + const {_} = useLingui() + const pal = usePalette('default') + return ( + } + size={24} + strokeWidth={1.7} + /> + ) : ( + } + size={24} + strokeWidth={1.7} + /> + ) + } + label={_(msg`Search`)} + accessibilityLabel={_(msg`Search`)} + accessibilityHint="" + bold={isActive} + onPress={onPress} + /> + ) +} +SearchMenuItem = React.memo(SearchMenuItem) + +let HomeMenuItem = ({ + isActive, + onPress, +}: { + isActive: boolean + onPress: () => void +}): React.ReactNode => { + const {_} = useLingui() + const pal = usePalette('default') + return ( + } + size="24" + strokeWidth={3.25} + /> + ) : ( + } + size="24" + strokeWidth={3.25} + /> + ) + } + label={_(msg`Home`)} + accessibilityLabel={_(msg`Home`)} + accessibilityHint="" + bold={isActive} + onPress={onPress} + /> + ) +} +HomeMenuItem = React.memo(HomeMenuItem) + +let NotificationsMenuItem = ({ + isActive, + onPress, +}: { + isActive: boolean + onPress: () => void +}): React.ReactNode => { + const {_} = useLingui() + const pal = usePalette('default') + const numUnreadNotifications = useUnreadNotifications() + return ( + } + size="24" + strokeWidth={1.7} + /> + ) : ( + } + size="24" + strokeWidth={1.7} + /> + ) + } + label={_(msg`Notifications`)} + accessibilityLabel={_(msg`Notifications`)} + accessibilityHint={ + numUnreadNotifications === '' ? '' : `${numUnreadNotifications} unread` + } + count={numUnreadNotifications} + bold={isActive} + onPress={onPress} + /> + ) +} +NotificationsMenuItem = React.memo(NotificationsMenuItem) + +let FeedsMenuItem = ({ + isActive, + onPress, +}: { + isActive: boolean + onPress: () => void +}): React.ReactNode => { + const {_} = useLingui() + const pal = usePalette('default') + return ( + + ) : ( + + ) + } + label={_(msg`Feeds`)} + accessibilityLabel={_(msg`Feeds`)} + accessibilityHint="" + bold={isActive} + onPress={onPress} + /> + ) +} +FeedsMenuItem = React.memo(FeedsMenuItem) + +let ListsMenuItem = ({onPress}: {onPress: () => void}): React.ReactNode => { + const {_} = useLingui() + const pal = usePalette('default') + return ( + } + label={_(msg`Lists`)} + accessibilityLabel={_(msg`Lists`)} + accessibilityHint="" + onPress={onPress} + /> + ) +} +ListsMenuItem = React.memo(ListsMenuItem) + +let ModerationMenuItem = ({ + onPress, +}: { + onPress: () => void +}): React.ReactNode => { + const {_} = useLingui() + const pal = usePalette('default') + return ( + } + label={_(msg`Moderation`)} + accessibilityLabel={_(msg`Moderation`)} + accessibilityHint="" + onPress={onPress} + /> + ) +} +ModerationMenuItem = React.memo(ModerationMenuItem) + +let ProfileMenuItem = ({ + isActive, + onPress, +}: { + isActive: boolean + onPress: () => void +}): React.ReactNode => { + const {_} = useLingui() + const pal = usePalette('default') + return ( + } + size="26" + strokeWidth={1.5} + /> + ) : ( + } + size="26" + strokeWidth={1.5} + /> + ) + } + label={_(msg`Profile`)} + accessibilityLabel={_(msg`Profile`)} + accessibilityHint="" + onPress={onPress} + /> + ) +} +ProfileMenuItem = React.memo(ProfileMenuItem) + +let SettingsMenuItem = ({onPress}: {onPress: () => void}): React.ReactNode => { + const {_} = useLingui() + const pal = usePalette('default') + return ( + } + size="26" + strokeWidth={1.75} + /> + } + label={_(msg`Settings`)} + accessibilityLabel={_(msg`Settings`)} + accessibilityHint="" + onPress={onPress} + /> + ) +} +SettingsMenuItem = React.memo(SettingsMenuItem) + function MenuItem({ icon, label, @@ -478,7 +605,7 @@ function MenuItem({ ) } -function InviteCodes({style}: {style?: StyleProp}) { +let InviteCodes = ({}: {}): React.ReactNode => { const {track} = useAnalytics() const setDrawerOpen = useSetDrawerOpen() const pal = usePalette('default') @@ -496,7 +623,7 @@ function InviteCodes({style}: {style?: StyleProp}) { return ( }) { ) } +InviteCodes = React.memo(InviteCodes) const styles = StyleSheet.create({ view: { @@ -595,7 +723,7 @@ const styles = StyleSheet.create({ }, inviteCodes: { - paddingLeft: 22, + paddingLeft: 0, paddingVertical: 8, flexDirection: 'row', }, diff --git a/src/view/shell/NavSignupCard.tsx b/src/view/shell/NavSignupCard.tsx index 7026dd2a..11dd7ffe 100644 --- a/src/view/shell/NavSignupCard.tsx +++ b/src/view/shell/NavSignupCard.tsx @@ -11,7 +11,7 @@ import {Button} from '#/view/com/util/forms/Button' import {useLoggedOutViewControls} from '#/state/shell/logged-out' import {useCloseAllActiveElements} from '#/state/util' -export function NavSignupCard() { +let NavSignupCard = ({}: {}): React.ReactNode => { const {_} = useLingui() const pal = usePalette('default') const {setShowLoggedOut} = useLoggedOutViewControls() @@ -59,3 +59,5 @@ export function NavSignupCard() { ) } +NavSignupCard = React.memo(NavSignupCard) +export {NavSignupCard}