Skip to content
This repository has been archived by the owner on Oct 4, 2023. It is now read-only.

Commit

Permalink
[C-1113] Improve native render performance (#1935)
Browse files Browse the repository at this point in the history
  • Loading branch information
dylanjeffers committed Sep 16, 2022
1 parent 7f4ede3 commit 16a8b96
Show file tree
Hide file tree
Showing 21 changed files with 235 additions and 147 deletions.
13 changes: 13 additions & 0 deletions packages/common/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions packages/common/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
"moment": "2.24.0",
"numeral": "2.0.6",
"promise.allsettled": "1.0.5",
"proxy-memoize": "1.2.0",
"reselect": "4.0.0",
"typed-redux-saga": "1.3.1",
"typesafe-actions": "5.1.0"
Expand Down
1 change: 1 addition & 0 deletions packages/common/src/hooks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ export * from './useTwitterButtonStatus'
export * from './useUIAudio'
export * from './useSelectTierInfo'
export * from './useGetFirstOrTopSupporter'
export * from './useProxySelector'
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import type { DependencyList } from 'react'
import { useCallback } from 'react'

import type { CommonState } from '@audius/common'
import memoize from 'proxy-memoize'
import { useSelector } from 'react-redux'

import type { CommonState } from '../store/commonStore'

const createProxySelectorHook = <TState extends object = any>() => {
const useProxySelector = <TReturnType>(
fn: (state: TState) => TReturnType,
Expand Down
14 changes: 7 additions & 7 deletions packages/common/src/hooks/useSelectTierInfo.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import { useSelector } from 'react-redux'

import { ID } from '../models'
import { CommonState, makeGetTierAndVerifiedForUser } from '../store'
import { makeGetTierAndVerifiedForUser } from '../store'

import { useProxySelector } from './useProxySelector'

const getTierAndVerifiedForUser = makeGetTierAndVerifiedForUser()

/**
* Wraps our reselect tier selector in useMemo and useSelector
* to be safe for use in multiple components
* @param userId
*/
export const useSelectTierInfo = (userId: ID) => {
return useSelector((state: CommonState) => {
return getTierAndVerifiedForUser(state, { userId })
})
return useProxySelector(
(state) => getTierAndVerifiedForUser(state, { userId }),
[userId]
)
}
26 changes: 14 additions & 12 deletions packages/mobile/src/components/feed-tip-tile/FeedTipTile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import {
accountSelectors,
cacheUsersSelectors,
tippingSelectors,
tippingActions
tippingActions,
useProxySelector
} from '@audius/common'
import {
dismissRecentTip,
Expand Down Expand Up @@ -62,18 +63,19 @@ export const FeedTipTile = () => {
const styles = useStyles()
const dispatch = useDispatch()
const account = useSelector(getAccountUser)

const showTip = useSelector(getShowTip)
const tipToDisplay = useSelector(getTipToDisplay)
const tipperIds = tipToDisplay
? [
tipToDisplay.sender_id,
tipToDisplay.receiver_id,
...tipToDisplay.followee_supporter_ids
]
: []
const usersMap = useSelector((state) =>
getUsers(state, { ids: tipToDisplay ? tipperIds : [] })
)

const { tipToDisplay, usersMap, tipperIds } = useProxySelector((state) => {
const tipToDisplay = getTipToDisplay(state)
if (!tipToDisplay) {
return { tipToDisplay: null, usersMap: {}, tipperIds: [] }
}
const { sender_id, receiver_id, followee_supporter_ids } = tipToDisplay
const tipperIds = [sender_id, receiver_id, ...followee_supporter_ids]
const usersMap = getUsers(state, { ids: tipperIds })
return { tipToDisplay, usersMap, tipperIds }
}, [])

useAsync(async () => {
const storage = await getRecentTipsStorage(localStorage)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import type {
CommonState
} from '@audius/common'
import {
useProxySelector,
playerSelectors,
FavoriteSource,
PlaybackSource,
Expand All @@ -29,7 +30,6 @@ import { useDispatch, useSelector } from 'react-redux'

import { useCollectionCoverArt } from 'app/hooks/useCollectionCoverArt'
import { useNavigation } from 'app/hooks/useNavigation'
import { useProxySelector } from 'app/hooks/useProxySelector'

import { CollectionTileTrackList } from './CollectionTileTrackList'
import { LineupTile } from './LineupTile'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import type { ComponentType, ReactNode } from 'react'
import { createContext } from 'react'
import { useMemo, createContext } from 'react'

import type { MaterialTopTabNavigationOptions } from '@react-navigation/material-top-tabs'
import type {
MaterialTopTabBarProps,
MaterialTopTabNavigationOptions
} from '@react-navigation/material-top-tabs'
import type { Animated } from 'react-native'
import { createMaterialCollapsibleTopTabNavigator } from 'react-native-collapsible-tab-view'
import type { SvgProps } from 'react-native-svg'
Expand All @@ -25,28 +28,33 @@ export const CollapsibleTabNavigatorContext =
scrollY: undefined
})

export const CollapsibleTabNavigatorContextProvider = ({
sceneName,
refreshing,
onRefresh,
scrollY,
children
}: {
type CollapsibleTabNavigatorContextProviderProps = {
sceneName: string
refreshing?: boolean
onRefresh?: () => void
scrollY?: Animated.Value
children: ReactNode
}) => {
}

export const CollapsibleTabNavigatorContextProvider = (
props: CollapsibleTabNavigatorContextProviderProps
) => {
const { sceneName, refreshing, onRefresh, scrollY, children } = props

const context = useMemo(
() => ({ sceneName, refreshing, onRefresh, scrollY }),
[sceneName, refreshing, onRefresh, scrollY]
)

return (
<CollapsibleTabNavigatorContext.Provider
value={{ sceneName, refreshing, onRefresh, scrollY }}
>
<CollapsibleTabNavigatorContext.Provider value={context}>
{children}
</CollapsibleTabNavigatorContext.Provider>
)
}

const tabBar = (props: MaterialTopTabBarProps) => <TopTabBar {...props} />

type CollapsibleTabNavigatorProps = {
/**
* Function that renders the collapsible header
Expand All @@ -71,18 +79,17 @@ export const CollapsibleTabNavigator = ({
children,
screenOptions
}: CollapsibleTabNavigatorProps) => {
const collapsibleOptions = useMemo(
() => ({ renderHeader, disableSnap: true, animatedValue }),
[renderHeader, animatedValue]
)

return (
<Tab.Navigator
collapsibleOptions={{
renderHeader,
disableSnap: true,
animatedValue
}}
collapsibleOptions={collapsibleOptions}
initialRouteName={initialScreenName}
tabBar={(props) => <TopTabBar {...props} />}
screenOptions={{
...screenOptions
}}
tabBar={tabBar}
screenOptions={screenOptions}
>
{children}
</Tab.Navigator>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { useCallback, useContext, useEffect, useState } from 'react'

import type { Notification } from '@audius/common'
import {
useProxySelector,
Status,
notificationsSelectors,
notificationsActions
Expand Down Expand Up @@ -102,7 +103,7 @@ const useIsViewable = () => {
export const NotificationList = () => {
const styles = useStyles()
const dispatch = useDispatch()
const notifications = useSelector(getNotifications)
const notifications = useProxySelector(getNotifications, [])
const status = useSelector(getNotificationStatus)
const hasMore = useSelector(getNotificationHasMore)
const [isRefreshing, setIsRefreshing] = useState(false)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import type { FavoriteNotification as FavoriteNotificationType } from '@audius/common'
import { formatCount, notificationsSelectors } from '@audius/common'
import { useSelector } from 'react-redux'
import {
formatCount,
notificationsSelectors,
useProxySelector
} from '@audius/common'

import IconHeart from 'app/assets/images/iconHeart.svg'

Expand Down Expand Up @@ -30,14 +33,18 @@ type FavoriteNotificationProps = {
export const FavoriteNotification = (props: FavoriteNotificationProps) => {
const { notification } = props
const { userIds, entityType } = notification
const users = useSelector((state) =>
getNotificationUsers(state, notification, USER_LENGTH_LIMIT)

const users = useProxySelector(
(state) => getNotificationUsers(state, notification, USER_LENGTH_LIMIT),
[notification]
)

const firstUser = users?.[0]
const otherUsersCount = userIds.length - 1

const entity = useSelector((state) =>
getNotificationEntity(state, notification)
const entity = useProxySelector(
(state) => getNotificationEntity(state, notification),
[notification]
)

const handlePress = useSocialActionHandler(notification, users)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import type { FollowNotification as FollowNotificationType } from '@audius/common'
import { formatCount, notificationsSelectors } from '@audius/common'
import { useSelector } from 'react-redux'
import {
useProxySelector,
formatCount,
notificationsSelectors
} from '@audius/common'

import IconUser from 'app/assets/images/iconUser.svg'

Expand Down Expand Up @@ -29,8 +32,9 @@ type FollowNotificationProps = {
export const FollowNotification = (props: FollowNotificationProps) => {
const { notification } = props
const { userIds } = notification
const users = useSelector((state) =>
getNotificationUsers(state, notification, USER_LENGTH_LIMIT)
const users = useProxySelector(
(state) => getNotificationUsers(state, notification, USER_LENGTH_LIMIT),
[notification]
)
const firstUser = users?.[0]
const otherUsersCount = userIds.length - 1
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import type { RepostNotification as RepostNotificationType } from '@audius/common'
import { formatCount, notificationsSelectors } from '@audius/common'
import { useSelector } from 'react-redux'
import {
useProxySelector,
formatCount,
notificationsSelectors
} from '@audius/common'

import IconRepost from 'app/assets/images/iconRepost.svg'

Expand Down Expand Up @@ -30,14 +33,16 @@ type RepostNotificationProps = {
export const RepostNotification = (props: RepostNotificationProps) => {
const { notification } = props
const { userIds, entityType } = notification
const users = useSelector((state) =>
getNotificationUsers(state, notification, USER_LENGTH_LIMIT)
const users = useProxySelector(
(state) => getNotificationUsers(state, notification, USER_LENGTH_LIMIT),
[notification]
)
const firstUser = users?.[0]
const otherUsersCount = userIds.length - 1

const entity = useSelector((state) =>
getNotificationEntity(state, notification)
const entity = useProxySelector(
(state) => getNotificationEntity(state, notification),
[notification]
)

const handlePress = useSocialActionHandler(notification, users)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import { useCallback } from 'react'

import type { UserSubscriptionNotification as UserSubscriptionNotificationType } from '@audius/common'
import { notificationsSelectors, Entity } from '@audius/common'
import {
useProxySelector,
notificationsSelectors,
Entity
} from '@audius/common'
import { View } from 'react-native'
import { useSelector } from 'react-redux'

Expand Down Expand Up @@ -37,8 +41,9 @@ export const UserSubscriptionNotification = (
const { entityType } = notification
const navigation = useDrawerNavigation()
const user = useSelector((state) => getNotificationUser(state, notification))
const entities = useSelector((state) =>
getNotificationEntities(state, notification)
const entities = useProxySelector(
(state) => getNotificationEntities(state, notification),
[notification]
)

const uploadCount = entities?.length ?? 0
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { ReactNode } from 'react'
import { createContext } from 'react'
import { useMemo, createContext } from 'react'

// eslint-disable-next-line import/no-unresolved
import type { DrawerNavigationHelpers } from '@react-navigation/drawer/lib/typescript/src/types'
Expand Down Expand Up @@ -31,7 +31,30 @@ type ProviderProps = ContextType & {
export const NotificationsDrawerNavigationContextProvider = (
props: ProviderProps
) => {
const { children, ...other } = props
const {
children,
drawerHelpers,
drawerNavigation,
gesturesDisabled,
setGesturesDisabled,
state
} = props
const other = useMemo(
() => ({
drawerHelpers,
drawerNavigation,
gesturesDisabled,
setGesturesDisabled,
state
}),
[
drawerHelpers,
drawerNavigation,
gesturesDisabled,
setGesturesDisabled,
state
]
)
return (
<NotificationsDrawerNavigationContext.Provider value={other}>
{children}
Expand Down

0 comments on commit 16a8b96

Please sign in to comment.