Skip to content

Commit

Permalink
perf: Reduce graphql requests in farms page (#9865)
Browse files Browse the repository at this point in the history
<!--
Before opening a pull request, please read the [contributing
guidelines](https://github.com/pancakeswap/pancake-frontend/blob/develop/CONTRIBUTING.md)
first
-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on restructuring import paths for helper functions in
the Info section of the web app. It updates import paths to improve
organization and consistency.

### Detailed summary
- Updated import paths for `infoDataHelpers` and `infoQueryHelpers` in
multiple files to `utils` directory
- Added new interfaces `V3FarmWithoutStakedValue` and
`V2FarmWithoutStakedValue` in `state/farms/types.ts`
- Updated import paths for `getChangeForPeriod` in various files to
`utils`
- Updated import paths for `getPercentChange` in multiple files to
`utils`
- Updated import paths for `useBCakeProxyContractAddress` in different
components and hooks to match new directory structure

> The following files were skipped due to too many changes:
`doc/Info.md`,
`apps/web/src/views/Farms/components/FarmCard/V3/FarmV3ApyButton.tsx`,
`apps/web/src/views/Farms/FarmsV3.tsx`,
`apps/web/src/state/farms/hooks.ts`

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your
question}`

<!-- end pr-codex -->
  • Loading branch information
memoyil authored May 28, 2024
1 parent f22bfce commit 90c565b
Show file tree
Hide file tree
Showing 30 changed files with 150 additions and 58 deletions.
2 changes: 1 addition & 1 deletion apps/web/src/__tests__/views/info/utils/infoData.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { getAmountChange, getPercentChange } from 'views/Info/utils/infoDataHelpers'
import { getAmountChange, getPercentChange } from 'utils/infoDataHelpers'
import { getLpFeesAndApr } from 'utils/getLpFeesAndApr'
import { getChangeForPeriod } from 'utils/getChangeForPeriod'

Expand Down
7 changes: 4 additions & 3 deletions apps/web/src/hooks/usePoolAvgInfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export interface UsePoolAvgInfoParams {
numberOfDays?: number
address?: string
chainId?: ChainId
enabled?: boolean
}

export const averageArray = (dataToCalculate: number[]): number => {
Expand All @@ -33,9 +34,9 @@ const defaultInfo: Info = {
feeUSD: 0,
}

export function usePoolAvgInfo({ address = '', numberOfDays = 7, chainId }: UsePoolAvgInfoParams) {
export function usePoolAvgInfo({ address = '', numberOfDays = 7, chainId, enabled = true }: UsePoolAvgInfoParams) {
const { data } = useQuery({
queryKey: [address, chainId],
queryKey: ['poolAvgInfo', address, chainId],

queryFn: async () => {
if (!chainId) return undefined
Expand Down Expand Up @@ -70,7 +71,7 @@ export function usePoolAvgInfo({ address = '', numberOfDays = 7, chainId }: UseP
}
},

enabled: Boolean(address && chainId),
enabled: Boolean(address && chainId && enabled),
refetchOnWindowFocus: false,
})

Expand Down
4 changes: 2 additions & 2 deletions apps/web/src/hooks/v3/useAllV3TicksQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,15 @@ export type AllV3TicksQuery = {
export type Ticks = AllV3TicksQuery['ticks']
export type TickData = Ticks[number]

export default function useAllV3TicksQuery(poolAddress: string | undefined, interval: number) {
export default function useAllV3TicksQuery(poolAddress: string | undefined, interval: number, enabled = true) {
const { chainId } = useActiveChainId()
const { data, isLoading, error } = useQuery({
queryKey: [`useAllV3TicksQuery-${poolAddress}-${chainId}`],
queryFn: async () => {
if (!chainId || !poolAddress) return undefined
return getPoolTicks(chainId, poolAddress)
},
enabled: Boolean(poolAddress && chainId && v3Clients[chainId]),
enabled: Boolean(poolAddress && chainId && v3Clients[chainId] && enabled),
refetchInterval: interval,
refetchOnMount: false,
refetchOnReconnect: false,
Expand Down
6 changes: 4 additions & 2 deletions apps/web/src/hooks/v3/usePoolTickData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,26 +18,28 @@ function useTicksFromSubgraph(
currencyA: Currency | undefined | null,
currencyB: Currency | undefined | null,
feeAmount: FeeAmount | undefined,
enabled = true,
) {
const poolAddress =
currencyA && currencyB && feeAmount
? Pool.getAddress(currencyA?.wrapped, currencyB?.wrapped, feeAmount, undefined)
: undefined

return useAllV3TicksQuery(poolAddress, 30000)
return useAllV3TicksQuery(poolAddress, 30000, enabled)
}

// Fetches all ticks for a given pool
export function useAllV3Ticks(
currencyA: Currency | undefined | null,
currencyB: Currency | undefined | null,
feeAmount: FeeAmount | undefined,
enabled = true,
): {
isLoading: boolean
error: unknown
ticks: TickData[] | undefined
} {
const subgraphTickData = useTicksFromSubgraph(currencyA, currencyB, feeAmount)
const subgraphTickData = useTicksFromSubgraph(currencyA, currencyB, feeAmount, enabled)

return {
isLoading: subgraphTickData.isLoading,
Expand Down
90 changes: 83 additions & 7 deletions apps/web/src/state/farms/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,28 @@ import { useMemo } from 'react'
import { useSelector } from 'react-redux'
import { useAppDispatch } from 'state'
import { getMasterChefContract } from 'utils/contractHelpers'
import { useBCakeProxyContractAddress } from 'views/Farms/hooks/useBCakeProxyContractAddress'
import { useBCakeProxyContractAddress } from 'hooks/useBCakeProxyContractAddress'

import useAccountActiveChain from 'hooks/useAccountActiveChain'
import {
fetchBCakeWrapperDataAsync,
fetchBCakeWrapperUserDataAsync,
fetchFarmsPublicDataAsync,
fetchFarmUserDataAsync,
} from '.'
import { v3Clients } from 'utils/graphql'
import { gql } from 'graphql-request'
import { averageArray } from 'hooks/usePoolAvgInfo'
import { multiQuery } from 'utils/infoQueryHelpers'
import mapKeys from 'lodash/mapKeys'
import mapValues from 'lodash/mapValues'
import { V2FarmWithoutStakedValue, V3FarmWithoutStakedValue } from 'state/farms/types'
import {
farmSelector,
makeFarmFromPidSelector,
makeLpTokenPriceFromLpSymbolSelector,
makeUserFarmFromPidSelector,
} from './selectors'
import {
fetchBCakeWrapperDataAsync,
fetchBCakeWrapperUserDataAsync,
fetchFarmsPublicDataAsync,
fetchFarmUserDataAsync,
} from '.'

export function useFarmsLength() {
const { chainId } = useActiveChainId()
Expand Down Expand Up @@ -63,6 +70,75 @@ export function useFarmV2PublicAPI() {
})
}

export const usePollFarmsAvgInfo = (activeFarms: (V3FarmWithoutStakedValue | V2FarmWithoutStakedValue)[]) => {
const { chainId } = useAccountActiveChain()

const activeFarmAddresses = useMemo(() => {
return activeFarms.map((farm) => farm.lpAddress).sort()
}, [activeFarms])

const { data } = useQuery({
queryKey: ['farmsAvgInfo', chainId, activeFarmAddresses],
placeholderData: {},
queryFn: async () => {
if (!chainId) return undefined
const client = v3Clients[chainId]
if (!client) {
console.error('[Failed] Trading volume', chainId)
return {}
}

const addresses = activeFarms
.map((farm) => farm.lpAddress)
.map((lpAddress) => {
return lpAddress.toLowerCase()
})

const rawResult: any | undefined = await multiQuery(
(subqueries) => gql`
query getVolume {
${subqueries}
}
`,
addresses.map(
(tokenAddress) => `
t${tokenAddress}:poolDayDatas(first: 7, orderBy: date, orderDirection: desc, where: { pool: "${tokenAddress.toLowerCase()}"}) {
volumeUSD
tvlUSD
feesUSD
protocolFeesUSD
}
`,
),
client,
)

const results = mapKeys(rawResult, (_, key) => {
return key.substring(1, key.length)
})

return mapValues(results, (value) => {
const volumes = value.map((d: { volumeUSD: string }) => Number(d.volumeUSD))
const feeUSDs = value.map(
(d: { feesUSD: string; protocolFeesUSD: string }) => Number(d.feesUSD) - Number(d.protocolFeesUSD),
)
return {
volumeUSD: averageArray(volumes),
tvlUSD: parseFloat(value[0]?.tvlUSD) || 0,
feeUSD: averageArray(feeUSDs),
}
})
},

enabled: Boolean(chainId && activeFarms?.length),
refetchOnReconnect: false,
refetchOnWindowFocus: false,
refetchOnMount: false,
})

return data
}

export const usePollFarmsWithUserData = () => {
const dispatch = useAppDispatch()
const { account, chainId } = useAccountActiveChain()
Expand Down
9 changes: 9 additions & 0 deletions apps/web/src/state/farms/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { DeserializedFarm, FarmV3DataWithPriceAndUserInfo } from '@pancakeswap/farms'

export interface V3FarmWithoutStakedValue extends FarmV3DataWithPriceAndUserInfo {
version: 3
}

export interface V2FarmWithoutStakedValue extends DeserializedFarm {
version: 2
}
2 changes: 1 addition & 1 deletion apps/web/src/state/info/queries/pools/poolData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { subgraphTokenSymbol } from 'state/info/constant'
import { Block, PoolData } from 'state/info/types'
import { getChangeForPeriod } from 'utils/getChangeForPeriod'
import { getLpFeesAndApr } from 'utils/getLpFeesAndApr'
import { getAmountChange, getPercentChange } from 'views/Info/utils/infoDataHelpers'
import { getAmountChange, getPercentChange } from 'utils/infoDataHelpers'

import { safeGetAddress } from 'utils'
import {
Expand Down
2 changes: 1 addition & 1 deletion apps/web/src/state/info/queries/protocol/overview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { Block, ProtocolData } from 'state/info/types'
import { getChangeForPeriod } from 'utils/getChangeForPeriod'
import { getDeltaTimestamps } from 'utils/getDeltaTimestamps'
import { useBlocksFromTimestamps } from 'views/Info/hooks/useBlocksFromTimestamps'
import { getPercentChange } from 'views/Info/utils/infoDataHelpers'
import { getPercentChange } from 'utils/infoDataHelpers'
import { MultiChainName, checkIsStableSwap, getMultiChainQueryEndPointWithStableSwap } from '../../constant'
import { useGetChainName } from '../../hooks'

Expand Down
2 changes: 1 addition & 1 deletion apps/web/src/state/info/queries/tokens/priceData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import orderBy from 'lodash/orderBy'

import { PriceChartEntry } from 'state/info/types'
import { getBlocksFromTimestamps } from 'utils/getBlocksFromTimestamps'
import { multiQuery } from 'views/Info/utils/infoQueryHelpers'
import { multiQuery } from 'utils/infoQueryHelpers'
import { MultiChainName, checkIsStableSwap, getMultiChainQueryEndPointWithStableSwap } from '../../constant'

interface FormattedHistory {
Expand Down
2 changes: 1 addition & 1 deletion apps/web/src/state/info/queries/tokens/tokenData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import { gql } from 'graphql-request'
import { Block, TokenData } from 'state/info/types'
import { getChangeForPeriod } from 'utils/getChangeForPeriod'
import { getAmountChange, getPercentChange } from 'views/Info/utils/infoDataHelpers'
import { getAmountChange, getPercentChange } from 'utils/infoDataHelpers'
import {
MultiChainNameExtend,
STABLESWAP_SUBGRAPHS_START_BLOCK,
Expand Down
2 changes: 1 addition & 1 deletion apps/web/src/state/swap/fetch/fetchDerivedPriceData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import orderBy from 'lodash/orderBy'
import { multiChainName } from 'state/info/constant'
import { Block } from 'state/info/types'
import { getBlocksFromTimestamps } from 'utils/getBlocksFromTimestamps'
import { multiQuery } from 'views/Info/utils/infoQueryHelpers'
import { multiQuery } from 'utils/infoQueryHelpers'
import { getDerivedPrices, getDerivedPricesQueryConstructor, getTVL } from '../queries/getDerivedPrices'
import { PairDataTimeWindowEnum } from '../types'

Expand Down
2 changes: 1 addition & 1 deletion apps/web/src/utils/getBlocksFromTimestamps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import orderBy from 'lodash/orderBy'
import { multiChainBlocksClient, multiChainName, MultiChainNameExtend } from 'state/info/constant'
import { ChainId, getLlamaChainName } from '@pancakeswap/chains'
import { Block } from 'state/info/types'
import { multiQuery } from 'views/Info/utils/infoQueryHelpers'
import { multiQuery } from 'utils/infoQueryHelpers'

const getBlockSubqueries = (timestamps: number[]) =>
timestamps.map((timestamp) => {
Expand Down
2 changes: 1 addition & 1 deletion apps/web/src/utils/getChangeForPeriod.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { getAmountChange, getPercentChange } from '../views/Info/utils/infoDataHelpers'
import { getAmountChange, getPercentChange } from './infoDataHelpers'

/**
* Given current value and value 1 and 2 periods (e.g. 1day + 2days, 1week - 2weeks) returns the amount change for latest period
Expand Down
File renamed without changes.
File renamed without changes.
24 changes: 6 additions & 18 deletions apps/web/src/views/Farms/FarmsV3.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,5 @@
import { ChainId } from '@pancakeswap/chains'
import {
DeserializedFarm,
FarmV3DataWithPriceAndUserInfo,
FarmWithStakedValue,
filterFarmsByQuery,
supportedChainIdV2,
supportedChainIdV3,
} from '@pancakeswap/farms'
import { FarmWithStakedValue, filterFarmsByQuery, supportedChainIdV2, supportedChainIdV3 } from '@pancakeswap/farms'
import { useIntersectionObserver } from '@pancakeswap/hooks'
import { useTranslation } from '@pancakeswap/localization'
import partition from 'lodash/partition'
Expand Down Expand Up @@ -40,7 +33,7 @@ import { useCakePrice } from 'hooks/useCakePrice'
import orderBy from 'lodash/orderBy'
import { useRouter } from 'next/router'
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import { useFarms, usePollFarmsWithUserData } from 'state/farms/hooks'
import { useFarms, usePollFarmsAvgInfo, usePollFarmsWithUserData } from 'state/farms/hooks'
import { useFarmsV3WithPositionsAndBooster } from 'state/farmsV3/hooks'
import { useCakeVaultUserData } from 'state/pools/hooks'
import { ViewMode } from 'state/user/actions'
Expand All @@ -50,6 +43,7 @@ import { getFarmApr } from 'utils/apr'
import { getStakedFarms } from 'views/Farms/utils/getStakedFarms'
import { BCakeMigrationBanner } from 'views/Home/components/Banners/BCakeMigrationBanner'
import { useAccount } from 'wagmi'
import { V2FarmWithoutStakedValue, V3FarmWithoutStakedValue } from 'state/farms/types'
import Table from './components/FarmTable/FarmTable'
import { FarmTypesFilter } from './components/FarmTypesFilter'
import { BCakeBoosterCard } from './components/YieldBooster/components/bCakeV3/BCakeBoosterCard'
Expand Down Expand Up @@ -166,18 +160,10 @@ const FinishedTextLink = styled(Link)`

const NUMBER_OF_FARMS_VISIBLE = 12

export interface V3FarmWithoutStakedValue extends FarmV3DataWithPriceAndUserInfo {
version: 3
}

export interface V3Farm extends V3FarmWithoutStakedValue {
version: 3
}

export interface V2FarmWithoutStakedValue extends DeserializedFarm {
version: 2
}

export interface V2Farm extends FarmWithStakedValue {
version: 2
}
Expand Down Expand Up @@ -271,6 +257,8 @@ const Farms: React.FC<React.PropsWithChildren> = ({ children }) => {
[farmsLP, v2PoolLength, v3PoolLength],
)

const farmsAvgInfo = usePollFarmsAvgInfo(activeFarms)

const archivedFarms = farmsLP

const stakedOnlyFarms = useMemo(() => getStakedFarms(activeFarms), [activeFarms])
Expand Down Expand Up @@ -426,7 +414,7 @@ const Farms: React.FC<React.PropsWithChildren> = ({ children }) => {
setQuery(event.target.value)
}, [])

const providerValue = useMemo(() => ({ chosenFarmsMemoized }), [chosenFarmsMemoized])
const providerValue = useMemo(() => ({ chosenFarmsMemoized, farmsAvgInfo }), [chosenFarmsMemoized, farmsAvgInfo])

return (
<FarmsV3Context.Provider value={providerValue}>
Expand Down
2 changes: 1 addition & 1 deletion apps/web/src/views/Farms/components/BCakeMigrateModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import useCatchTxError from 'hooks/useCatchTxError'
import { useBCakeProxyContract, useERC20 } from 'hooks/useContract'
import { useEffect, useMemo, useState } from 'react'
import { styled } from 'styled-components'
import { useBCakeProxyContractAddress } from '../hooks/useBCakeProxyContractAddress'
import { useBCakeProxyContractAddress } from '../../../hooks/useBCakeProxyContractAddress'
import useProxyStakedActions from './YieldBooster/hooks/useProxyStakedActions'

export const StepperCircle = styled.div`
Expand Down
2 changes: 1 addition & 1 deletion apps/web/src/views/Farms/components/FarmCard/ApyButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import { MouseEvent, useCallback, useMemo } from 'react'
import { useFarmFromPid, useFarmUser } from 'state/farms/hooks'

import { BIG_ZERO } from '@pancakeswap/utils/bigNumber'
import { V2FarmWithoutStakedValue, V3FarmWithoutStakedValue } from 'views/Farms/FarmsV3'
import { useAccount } from 'wagmi'
import { V2FarmWithoutStakedValue, V3FarmWithoutStakedValue } from 'state/farms/types'

export interface ApyButtonProps {
variant: 'text' | 'text-and-button'
Expand Down
Loading

0 comments on commit 90c565b

Please sign in to comment.