Virtualize item list scrolling
This helps the render time by a lot!
This commit is contained in:
parent
cc4e1f611f
commit
be3a162a8a
3 changed files with 113 additions and 11 deletions
|
@ -49,6 +49,7 @@
|
|||
"react-router-hash-link": "^2.4.3",
|
||||
"react-scripts": "^4.0.1",
|
||||
"react-transition-group": "^4.3.0",
|
||||
"react-virtualized": "^9.22.3",
|
||||
"simple-markdown": "^0.7.2",
|
||||
"tweenjs": "^1.0.2",
|
||||
"typescript": "^4.1.3",
|
||||
|
|
|
@ -25,6 +25,11 @@ import {
|
|||
import { gql, useMutation, useQuery } from "@apollo/client";
|
||||
import { Link, useParams } from "react-router-dom";
|
||||
import { HashLink } from "react-router-hash-link";
|
||||
import {
|
||||
List as VirtualizedList,
|
||||
AutoSizer,
|
||||
WindowScroller,
|
||||
} from "react-virtualized";
|
||||
|
||||
import { Heading1, Heading3, MajorErrorMessage, usePageTitle } from "./util";
|
||||
import HangerSpinner from "./components/HangerSpinner";
|
||||
|
@ -399,17 +404,10 @@ export function ClosetListContents({
|
|||
return (
|
||||
<Box>
|
||||
{itemsToShow.length > 0 ? (
|
||||
<Wrap spacing="4" justify="center">
|
||||
{itemsToShow.map((item) => (
|
||||
<WrapItem key={item.id}>
|
||||
<ItemCard
|
||||
item={item}
|
||||
variant="grid"
|
||||
tradeMatchingMode={tradeMatchingMode}
|
||||
/>
|
||||
</WrapItem>
|
||||
))}
|
||||
</Wrap>
|
||||
<ClosetItemList
|
||||
items={itemsToShow}
|
||||
tradeMatchingMode={tradeMatchingMode}
|
||||
/>
|
||||
) : (
|
||||
<Box fontStyle="italic">This list is empty!</Box>
|
||||
)}
|
||||
|
@ -442,6 +440,79 @@ export function ClosetListContents({
|
|||
);
|
||||
}
|
||||
|
||||
// HACK: Measured by hand from <SquareItemCard />, plus 16px padding.
|
||||
const ITEM_CARD_WIDTH = 112 + 16;
|
||||
const ITEM_CARD_HEIGHT = 171 + 16;
|
||||
|
||||
function ClosetItemList({ items, tradeMatchingMode }) {
|
||||
const renderItem = (item) => (
|
||||
<ItemCard
|
||||
key={item.id}
|
||||
item={item}
|
||||
variant="grid"
|
||||
tradeMatchingMode={tradeMatchingMode}
|
||||
/>
|
||||
);
|
||||
|
||||
// For small lists, we don't bother to virtualize, because it slows down
|
||||
// scrolling! (This helps a lot on the lists index page.)
|
||||
if (items.length < 30) {
|
||||
return (
|
||||
<Wrap spacing="4" justify="center">
|
||||
{items.map((item) => (
|
||||
<WrapItem key={item.id}>{renderItem(item)}</WrapItem>
|
||||
))}
|
||||
</Wrap>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<WindowScroller>
|
||||
{({ height, isScrolling, onChildScroll, scrollTop, registerChild }) => (
|
||||
<AutoSizer disableHeight>
|
||||
{({ width }) => {
|
||||
const numItemsPerRow = Math.floor(width / ITEM_CARD_WIDTH);
|
||||
const numRows = Math.ceil(items.length / numItemsPerRow);
|
||||
|
||||
return (
|
||||
<div ref={registerChild}>
|
||||
<VirtualizedList
|
||||
autoHeight
|
||||
height={height}
|
||||
width={width}
|
||||
rowCount={numRows}
|
||||
rowHeight={ITEM_CARD_HEIGHT}
|
||||
rowRenderer={({ index: rowIndex, key, style }) => {
|
||||
const firstItemIndex = rowIndex * numItemsPerRow;
|
||||
const itemsForRow = items.slice(
|
||||
firstItemIndex,
|
||||
firstItemIndex + numItemsPerRow
|
||||
);
|
||||
|
||||
return (
|
||||
<HStack
|
||||
key={key}
|
||||
style={style}
|
||||
spacing="4"
|
||||
justify="center"
|
||||
>
|
||||
{itemsForRow.map(renderItem)}
|
||||
</HStack>
|
||||
);
|
||||
}}
|
||||
isScrolling={isScrolling}
|
||||
onScroll={onChildScroll}
|
||||
scrollTop={scrollTop}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}}
|
||||
</AutoSizer>
|
||||
)}
|
||||
</WindowScroller>
|
||||
);
|
||||
}
|
||||
|
||||
export function buildClosetListPath(closetList) {
|
||||
let ownsOrWants;
|
||||
if (closetList.ownsOrWantsItems === "OWNS") {
|
||||
|
|
30
yarn.lock
30
yarn.lock
|
@ -7884,6 +7884,11 @@ clone-response@^1.0.2:
|
|||
dependencies:
|
||||
mimic-response "^1.0.0"
|
||||
|
||||
clsx@^1.0.4:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.1.1.tgz#98b3134f9abbdf23b2663491ace13c5c03a73188"
|
||||
integrity sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA==
|
||||
|
||||
co@^4.6.0:
|
||||
version "4.6.0"
|
||||
resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184"
|
||||
|
@ -9091,6 +9096,14 @@ dom-helpers@^5.0.1:
|
|||
"@babel/runtime" "^7.8.7"
|
||||
csstype "^2.6.7"
|
||||
|
||||
dom-helpers@^5.1.3:
|
||||
version "5.2.1"
|
||||
resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-5.2.1.tgz#d9400536b2bf8225ad98fe052e029451ac40e902"
|
||||
integrity sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.8.7"
|
||||
csstype "^3.0.2"
|
||||
|
||||
dom-serializer@0:
|
||||
version "0.2.2"
|
||||
resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.2.2.tgz#1afb81f533717175d478655debc5e332d9f9bb51"
|
||||
|
@ -15993,6 +16006,11 @@ react-is@^17.0.1:
|
|||
resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.1.tgz#5b3531bd76a645a4c9fb6e693ed36419e3301339"
|
||||
integrity sha512-NAnt2iGDXohE5LI7uBnLnqvLQMtzhkiAOLXTmv+qnF9Ky7xAPcX8Up/xWIhxvLVGJvuLiNc4xQLtuqDRzb4fSA==
|
||||
|
||||
react-lifecycles-compat@^3.0.4:
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362"
|
||||
integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==
|
||||
|
||||
react-refresh@^0.8.3:
|
||||
version "0.8.3"
|
||||
resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.8.3.tgz#721d4657672d400c5e3c75d063c4a85fb2d5d68f"
|
||||
|
@ -16145,6 +16163,18 @@ react-transition-group@^4.3.0:
|
|||
loose-envify "^1.4.0"
|
||||
prop-types "^15.6.2"
|
||||
|
||||
react-virtualized@^9.22.3:
|
||||
version "9.22.3"
|
||||
resolved "https://registry.yarnpkg.com/react-virtualized/-/react-virtualized-9.22.3.tgz#f430f16beb0a42db420dbd4d340403c0de334421"
|
||||
integrity sha512-MKovKMxWTcwPSxE1kK1HcheQTWfuCxAuBoSTf2gwyMM21NdX/PXUhnoP8Uc5dRKd+nKm8v41R36OellhdCpkrw==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.7.2"
|
||||
clsx "^1.0.4"
|
||||
dom-helpers "^5.1.3"
|
||||
loose-envify "^1.4.0"
|
||||
prop-types "^15.7.2"
|
||||
react-lifecycles-compat "^3.0.4"
|
||||
|
||||
react@^17.0.1:
|
||||
version "17.0.1"
|
||||
resolved "https://registry.yarnpkg.com/react/-/react-17.0.1.tgz#6e0600416bd57574e3f86d92edba3d9008726127"
|
||||
|
|
Loading…
Reference in a new issue