Skip to content

Commit

Permalink
Merge pull request #296 from reservoirprotocol/pedro/grwth-3093-impro…
Browse files Browse the repository at this point in the history
…ve-caching-performance-on-explorer

Improve SSR caching performance on explorer
  • Loading branch information
pedromcunha authored Aug 9, 2023
2 parents ee496b5 + c6ca4ac commit 276c1fc
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 123 deletions.
26 changes: 9 additions & 17 deletions pages/[chain]/asset/[assetId].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,7 @@ import { TokenActivityTable } from 'components/token/ActivityTable'
import { TokenInfo } from 'components/token/TokenInfo'
import { ToastContext } from 'context/ToastContextProvider'
import { useENSResolver, useMarketplaceChain, useMounted } from 'hooks'
import {
GetStaticPaths,
GetStaticProps,
InferGetStaticPropsType,
NextPage,
} from 'next'
import { GetServerSideProps, InferGetServerSidePropsType, NextPage } from 'next'
import Link from 'next/link'
import { useRouter } from 'next/router'
import { NORMALIZE_ROYALTIES } from 'pages/_app'
Expand All @@ -55,7 +50,7 @@ import { Head } from 'components/Head'
import { OffersTable } from 'components/token/OffersTable'
import { ListingsTable } from 'components/token/ListingsTable'

type Props = InferGetStaticPropsType<typeof getStaticProps>
type Props = InferGetServerSidePropsType<typeof getServerSideProps>

type ActivityTypes = Exclude<
NonNullable<
Expand Down Expand Up @@ -596,20 +591,13 @@ const IndexPage: NextPage<Props> = ({ assetId, ssr }) => {
)
}

export const getStaticPaths: GetStaticPaths = async () => {
return {
paths: [],
fallback: 'blocking',
}
}

export const getStaticProps: GetStaticProps<{
export const getServerSideProps: GetServerSideProps<{
assetId?: string
ssr: {
collection: paths['/collections/v5']['get']['responses']['200']['schema']
tokens: paths['/tokens/v6']['get']['responses']['200']['schema']
}
}> = async ({ params }) => {
}> = async ({ params, res }) => {
const assetId = params?.assetId ? params.assetId.toString().split(':') : []
let collectionId = assetId[0]
const id = assetId[1]
Expand Down Expand Up @@ -662,9 +650,13 @@ export const getStaticProps: GetStaticProps<{
? (collectionsResponse.data as Props['ssr']['collection'])
: {}

res.setHeader(
'Cache-Control',
'public, s-maxage=30, stale-while-revalidate=60'
)

return {
props: { assetId: params?.assetId as string, ssr: { collection, tokens } },
revalidate: 20,
}
}

Expand Down
76 changes: 31 additions & 45 deletions pages/[chain]/collection-rankings/index.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
import {
GetStaticPaths,
GetStaticProps,
InferGetStaticPropsType,
NextPage,
} from 'next'
import { GetServerSideProps, InferGetServerSidePropsType, NextPage } from 'next'
import { Text, Flex, Box } from 'components/primitives'
import Layout from 'components/Layout'
import {
Expand All @@ -19,7 +14,7 @@ import { paths } from '@reservoir0x/reservoir-sdk'
import { useCollections } from '@reservoir0x/reservoir-kit-ui'
import fetcher from 'utils/fetcher'
import { NORMALIZE_ROYALTIES } from '../../_app'
import supportedChains from 'utils/chains'
import supportedChains, { DefaultChain } from 'utils/chains'
import { CollectionRankingsTable } from 'components/rankings/CollectionRankingsTable'
import { useIntersectionObserver } from 'usehooks-ts'
import LoadingSpinner from 'components/common/LoadingSpinner'
Expand All @@ -31,7 +26,7 @@ import { Head } from 'components/Head'
import { ChainContext } from 'context/ChainContextProvider'
import { useRouter } from 'next/router'

type Props = InferGetStaticPropsType<typeof getStaticProps>
type Props = InferGetServerSidePropsType<typeof getServerSideProps>

const IndexPage: NextPage<Props> = ({ ssr }) => {
const router = useRouter()
Expand Down Expand Up @@ -73,7 +68,7 @@ const IndexPage: NextPage<Props> = ({ ssr }) => {
const { data, fetchNextPage, isFetchingPage, isValidating } = useCollections(
collectionQuery,
{
fallbackData: [ssr.collections[marketplaceChain.id]],
fallbackData: [ssr.collection],
}
)

Expand Down Expand Up @@ -168,57 +163,48 @@ const IndexPage: NextPage<Props> = ({ ssr }) => {
)
}

export const getStaticPaths: GetStaticPaths = async () => {
return {
paths: [],
fallback: 'blocking',
}
}

type CollectionSchema =
paths['/collections/v5']['get']['responses']['200']['schema']
type ChainCollections = Record<string, CollectionSchema>

export const getStaticProps: GetStaticProps<{
export const getServerSideProps: GetServerSideProps<{
ssr: {
collections: ChainCollections
collection: CollectionSchema
}
}> = async () => {
}> = async ({ res, params }) => {
const collectionQuery: paths['/collections/v5']['get']['parameters']['query'] =
{
sortBy: '1DayVolume',
normalizeRoyalties: NORMALIZE_ROYALTIES,
limit: 20,
includeTopBid: true,
}

const promises: ReturnType<typeof fetcher>[] = []
supportedChains.forEach((chain) => {
const query = { ...collectionQuery }
if (chain.collectionSetId) {
query.collectionsSetId = chain.collectionSetId
} else if (chain.community) {
query.community = chain.community
}
promises.push(
fetcher(`${chain.reservoirBaseUrl}/collections/v5`, query, {
headers: {
'x-api-key': chain.apiKey || '',
},
})
)
})
const responses = await Promise.allSettled(promises)
const collections: ChainCollections = {}
responses.forEach((response, i) => {
if (response.status === 'fulfilled') {
collections[supportedChains[i].id] = response.value.data
const chainPrefix = params?.chain || ''
const chain =
supportedChains.find((chain) => chain.routePrefix === chainPrefix) ||
DefaultChain
const query = { ...collectionQuery }
if (chain.collectionSetId) {
query.collectionsSetId = chain.collectionSetId
} else if (chain.community) {
query.community = chain.community
}
const response = await fetcher(
`${chain.reservoirBaseUrl}/collections/v5`,
query,
{
headers: {
'x-api-key': chain.apiKey || '',
},
}
})
)

res.setHeader(
'Cache-Control',
'public, s-maxage=30, stale-while-revalidate=60'
)

return {
props: { ssr: { collections } },
revalidate: 5,
props: { ssr: { collection: response.data } },
}
}

Expand Down
26 changes: 9 additions & 17 deletions pages/[chain]/collection/[contract].tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
import {
GetStaticPaths,
GetStaticProps,
InferGetStaticPropsType,
NextPage,
} from 'next'
import { GetServerSideProps, InferGetServerSidePropsType, NextPage } from 'next'
import { Text, Flex, Box } from '../../../components/primitives'
import {
useCollections,
Expand Down Expand Up @@ -66,7 +61,7 @@ type ActivityTypes = Exclude<
string
>

type Props = InferGetStaticPropsType<typeof getStaticProps>
type Props = InferGetServerSidePropsType<typeof getServerSideProps>

const CollectionPage: NextPage<Props> = ({ id, ssr }) => {
const router = useRouter()
Expand Down Expand Up @@ -669,21 +664,14 @@ const CollectionPage: NextPage<Props> = ({ id, ssr }) => {
)
}

export const getStaticPaths: GetStaticPaths = async () => {
return {
paths: [],
fallback: 'blocking',
}
}

export const getStaticProps: GetStaticProps<{
export const getServerSideProps: GetServerSideProps<{
ssr: {
collection?: paths['/collections/v5']['get']['responses']['200']['schema']
tokens?: paths['/tokens/v6']['get']['responses']['200']['schema']
hasAttributes: boolean
}
id: string | undefined
}> = async ({ params }) => {
}> = async ({ params, res }) => {
const id = params?.contract?.toString()
const { reservoirBaseUrl, apiKey, routePrefix } =
supportedChains.find((chain) => params?.chain === chain.routePrefix) ||
Expand Down Expand Up @@ -743,9 +731,13 @@ export const getStaticProps: GetStaticProps<{
(token) => (token?.token?.attributes?.length || 0) > 0
) || false

res.setHeader(
'Cache-Control',
'public, s-maxage=30, stale-while-revalidate=60'
)

return {
props: { ssr: { collection, tokens, hasAttributes }, id },
revalidate: 30,
}
}

Expand Down
72 changes: 28 additions & 44 deletions pages/[chain]/index.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,12 @@
import {
GetStaticPaths,
GetStaticProps,
InferGetStaticPropsType,
NextPage,
} from 'next'
import { GetServerSideProps, InferGetServerSidePropsType, NextPage } from 'next'
import { Text, Flex, Box } from 'components/primitives'
import Layout from 'components/Layout'
import { paths } from '@reservoir0x/reservoir-sdk'
import { useContext, useEffect, useMemo, useState } from 'react'
import { Footer } from 'components/home/Footer'
import { useMediaQuery } from 'react-responsive'
import { useMarketplaceChain, useMounted } from 'hooks'
import supportedChains from 'utils/chains'
import supportedChains, { DefaultChain } from 'utils/chains'
import { Head } from 'components/Head'
import { ChainContext } from 'context/ChainContextProvider'
import { Dropdown, DropdownMenuItem } from 'components/primitives/Dropdown'
Expand All @@ -25,7 +20,7 @@ import { FillTypeToggle } from 'components/home/FillTypeToggle'
import { TimeFilterToggle } from 'components/home/TimeFilterToggle'
import fetcher from 'utils/fetcher'

type Props = InferGetStaticPropsType<typeof getStaticProps>
type Props = InferGetServerSidePropsType<typeof getServerSideProps>

const IndexPage: NextPage<Props> = ({ ssr }) => {
const isSSR = typeof window === 'undefined'
Expand Down Expand Up @@ -58,9 +53,9 @@ const IndexPage: NextPage<Props> = ({ ssr }) => {
{
revalidateOnMount: true,
refreshInterval: 300000,
fallbackData: [
ssr.topSellingCollections[marketplaceChain.id].collections,
],
fallbackData: ssr.topSellingCollections[marketplaceChain.id]?.collections
? [ssr.topSellingCollections[marketplaceChain.id].collections]
: [],
},
chain?.id
)
Expand Down Expand Up @@ -233,62 +228,51 @@ const IndexPage: NextPage<Props> = ({ ssr }) => {
)
}

export const getStaticPaths: GetStaticPaths = async () => {
return {
paths: [],
fallback: 'blocking',
}
}

type TopSellingCollectionsSchema =
paths['/collections/top-selling/v1']['get']['responses']['200']['schema']

type ChainTopSellingCollections = Record<string, TopSellingCollectionsSchema>

type CollectionSchema =
paths['/collections/v5']['get']['responses']['200']['schema']
type ChainCollections = Record<string, CollectionSchema>

export const getStaticProps: GetStaticProps<{
export const getServerSideProps: GetServerSideProps<{
ssr: {
topSellingCollections: ChainTopSellingCollections
}
}> = async () => {
}> = async ({ params, res }) => {
const now = new Date()
const timestamp = Math.floor(now.getTime() / 1000)
const startTime = timestamp - 1440 * 60 // 24hrs ago

let topSellingCollectionsQuery: paths['/collections/top-selling/v1']['get']['parameters']['query'] =
const topSellingCollectionsQuery: paths['/collections/top-selling/v1']['get']['parameters']['query'] =
{
startTime: startTime,
fillType: 'sale',
limit: 20,
includeRecentSales: true,
}

const promises: ReturnType<typeof fetcher>[] = []
supportedChains.forEach((chain) => {
const query = { ...topSellingCollectionsQuery }

promises.push(
fetcher(`${chain.reservoirBaseUrl}/collections/top-selling/v1`, query, {
headers: {
'x-api-key': chain.apiKey || '',
},
})
)
})
const responses = await Promise.allSettled(promises)
const topSellingCollections: ChainTopSellingCollections = {}
responses.forEach((response, i) => {
if (response.status === 'fulfilled') {
topSellingCollections[supportedChains[i].id] = response.value.data
const chainPrefix = params?.chain || ''
const chain =
supportedChains.find((chain) => chain.routePrefix === chainPrefix) ||
DefaultChain
const response = await fetcher(
`${chain.reservoirBaseUrl}/collections/top-selling/v1`,
topSellingCollectionsQuery,
{
headers: {
'x-api-key': chain.apiKey || '',
},
}
})
)
const topSellingCollections: ChainTopSellingCollections = {}
topSellingCollections[chain.id] = response.data

res.setHeader(
'Cache-Control',
'public, s-maxage=120, stale-while-revalidate=180'
)

return {
props: { ssr: { topSellingCollections } },
revalidate: 5,
}
}

Expand Down

2 comments on commit 276c1fc

@vercel
Copy link

@vercel vercel bot commented on 276c1fc Aug 9, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vercel
Copy link

@vercel vercel bot commented on 276c1fc Aug 9, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

artblocks-v2 – ./

artblocks-v2-git-main-unevenlabs.vercel.app
artblocks-v2.vercel.app
artblocks-v2-unevenlabs.vercel.app

Please sign in to comment.