Preload next/prev user outfits page

Even in production, scrolling is a bit slow! This will preload the pagination one click ahead.

There is a bit of a perf downside, in that if you click through the pages too fast, you'll trigger _extra_ requests. I think that's a net win though, and I'm not gonna try to get cleverer than this right now.
This commit is contained in:
Emi Matchu 2021-11-01 19:50:21 -07:00
parent 299561d1e3
commit 12d525e3ab

View file

@ -20,6 +20,38 @@ function UserOutfitsPage() {
); );
} }
const USER_OUTFITS_PAGE_QUERY = gql`
query UserOutfitsPageContent($offset: Int!) {
currentUser {
id
numTotalOutfits
outfits(limit: 20, offset: $offset) {
id
name
updatedAt
# For alt text
petAppearance {
species {
id
name
}
color {
id
name
}
}
wornItems {
id
name
}
}
}
}
`;
const PER_PAGE = 20;
function UserOutfitsPageContent() { function UserOutfitsPageContent() {
const { isLoading: userLoading } = useRequireLogin(); const { isLoading: userLoading } = useRequireLogin();
@ -27,35 +59,7 @@ function UserOutfitsPageContent() {
const offset = parseInt(new URLSearchParams(search).get("offset")) || 0; const offset = parseInt(new URLSearchParams(search).get("offset")) || 0;
const { loading: queryLoading, error, data } = useQuery( const { loading: queryLoading, error, data } = useQuery(
gql` USER_OUTFITS_PAGE_QUERY,
query UserOutfitsPageContent($offset: Int!) {
currentUser {
id
numTotalOutfits
outfits(limit: 20, offset: $offset) {
id
name
updatedAt
# For alt text
petAppearance {
species {
id
name
}
color {
id
name
}
}
wornItems {
id
name
}
}
}
}
`,
{ {
variables: { offset }, variables: { offset },
context: { sendAuth: true }, context: { sendAuth: true },
@ -66,6 +70,26 @@ function UserOutfitsPageContent() {
} }
); );
const numTotalOutfits = data?.currentUser?.numTotalOutfits || null;
// Preload the previous and next pages. (Sigh, if we were doing cool Next.js
// stuff, this would already be happening by next/link magic I think!)
const prevPageOffset = offset - PER_PAGE;
const nextPageOffset = offset + PER_PAGE;
useQuery(USER_OUTFITS_PAGE_QUERY, {
variables: { offset: prevPageOffset },
context: { sendAuth: true },
skip: userLoading || offset === 0 || prevPageOffset < 0,
});
useQuery(USER_OUTFITS_PAGE_QUERY, {
variables: { offset: nextPageOffset },
context: { sendAuth: true },
skip:
userLoading ||
numTotalOutfits == null ||
nextPageOffset >= numTotalOutfits,
});
const isLoading = userLoading || queryLoading; const isLoading = userLoading || queryLoading;
if (error) { if (error) {
@ -78,8 +102,8 @@ function UserOutfitsPageContent() {
<Box> <Box>
<PaginationToolbar <PaginationToolbar
isLoading={isLoading} isLoading={isLoading}
totalCount={data?.currentUser?.numTotalOutfits} totalCount={numTotalOutfits}
numPerPage={20} numPerPage={PER_PAGE}
/> />
<Box height="6" /> <Box height="6" />
{isLoading ? ( {isLoading ? (
@ -100,8 +124,8 @@ function UserOutfitsPageContent() {
<Box height="6" /> <Box height="6" />
<PaginationToolbar <PaginationToolbar
isLoading={isLoading} isLoading={isLoading}
totalCount={data?.currentUser?.numTotalOutfits} totalCount={numTotalOutfits}
numPerPage={20} numPerPage={PER_PAGE}
/> />
</Box> </Box>
); );