use react-virtualized to speed up user items page

There's a known bug that items with a lot of zones will overflow the row… filing that as a separate fix tho!
This commit is contained in:
Emi Matchu 2020-12-07 18:58:10 -08:00
parent 6762c6d3fa
commit 0c2ec4685e
4 changed files with 79 additions and 5 deletions

View file

@ -37,6 +37,7 @@
"react-router-dom": "^5.1.2", "react-router-dom": "^5.1.2",
"react-scripts": "3.4.1", "react-scripts": "3.4.1",
"react-transition-group": "^4.3.0", "react-transition-group": "^4.3.0",
"react-virtualized": "^9.22.2",
"simple-markdown": "^0.7.2", "simple-markdown": "^0.7.2",
"xmlrpc": "^1.3.2" "xmlrpc": "^1.3.2"
}, },

View file

@ -17,6 +17,7 @@ import {
Portal, Portal,
Wrap, Wrap,
VStack, VStack,
useBreakpointValue,
useToast, useToast,
} from "@chakra-ui/core"; } from "@chakra-ui/core";
import { import {
@ -30,6 +31,7 @@ import {
import gql from "graphql-tag"; import gql from "graphql-tag";
import { useHistory, useParams } from "react-router-dom"; import { useHistory, useParams } from "react-router-dom";
import { useQuery, useLazyQuery, useMutation } from "@apollo/client"; import { useQuery, useLazyQuery, useMutation } from "@apollo/client";
import { AutoSizer, Grid, WindowScroller } from "react-virtualized";
import SimpleMarkdown from "simple-markdown"; import SimpleMarkdown from "simple-markdown";
import DOMPurify from "dompurify"; import DOMPurify from "dompurify";
@ -37,7 +39,6 @@ import HangerSpinner from "./components/HangerSpinner";
import { Heading1, Heading2, Heading3 } from "./util"; import { Heading1, Heading2, Heading3 } from "./util";
import ItemCard, { import ItemCard, {
ItemBadgeList, ItemBadgeList,
ItemCardList,
ItemKindBadge, ItemKindBadge,
YouOwnThisBadge, YouOwnThisBadge,
YouWantThisBadge, YouWantThisBadge,
@ -234,7 +235,13 @@ function UserItemsPage() {
<Heading2 id="owned-items" marginBottom="2"> <Heading2 id="owned-items" marginBottom="2">
{isCurrentUser ? "Items you own" : `Items ${data.user.username} owns`} {isCurrentUser ? "Items you own" : `Items ${data.user.username} owns`}
</Heading2> </Heading2>
<VStack spacing="8" alignItems="stretch"> <VStack
spacing="8"
alignItems="stretch"
className={css`
clear: both;
`}
>
{listsOfOwnedItems.map((closetList) => ( {listsOfOwnedItems.map((closetList) => (
<ClosetList <ClosetList
key={closetList.id} key={closetList.id}
@ -437,7 +444,7 @@ function ClosetList({ closetList, isCurrentUser, showHeading }) {
</Box> </Box>
)} )}
{sortedItems.length > 0 ? ( {sortedItems.length > 0 ? (
<ItemCardList> <VirtualizedItemCardList>
{sortedItems.map((item) => ( {sortedItems.map((item) => (
<ItemCard <ItemCard
key={item.id} key={item.id}
@ -454,7 +461,7 @@ function ClosetList({ closetList, isCurrentUser, showHeading }) {
} }
/> />
))} ))}
</ItemCardList> </VirtualizedItemCardList>
) : ( ) : (
<Box fontStyle="italic">This list is empty!</Box> <Box fontStyle="italic">This list is empty!</Box>
)} )}
@ -462,6 +469,51 @@ function ClosetList({ closetList, isCurrentUser, showHeading }) {
); );
} }
function VirtualizedItemCardList({ children }) {
const columnCount = useBreakpointValue({ base: 1, md: 2, lg: 3 });
const rowCount = Math.ceil(children.length / columnCount);
return (
<AutoSizer disableHeight>
{({ width }) => (
<WindowScroller>
{({
height,
isScrolling,
onChildScroll,
scrollTop,
registerChild,
}) => (
<Box ref={registerChild}>
<Grid
cellRenderer={({ key, rowIndex, columnIndex, style }) => (
<Box
key={key}
style={style}
paddingLeft={columnIndex > 0 ? "6" : "0"}
>
{children[rowIndex * columnCount + columnIndex]}
</Box>
)}
columnCount={columnCount}
columnWidth={width / columnCount}
rowCount={rowCount}
rowHeight={100}
width={width}
height={height}
autoHeight
isScrolling={isScrolling}
onScroll={onChildScroll}
scrollTop={scrollTop}
/>
</Box>
)}
</WindowScroller>
)}
</AutoSizer>
);
}
const unsafeMarkdownRules = { const unsafeMarkdownRules = {
autolink: SimpleMarkdown.defaultRules.autolink, autolink: SimpleMarkdown.defaultRules.autolink,
br: SimpleMarkdown.defaultRules.br, br: SimpleMarkdown.defaultRules.br,

View file

@ -22,6 +22,7 @@ function ItemCard({ item, badges, ...props }) {
<Box <Box
as={Link} as={Link}
to={`/items/${item.id}`} to={`/items/${item.id}`}
display="block"
p="2" p="2"
boxShadow="lg" boxShadow="lg"
borderRadius="lg" borderRadius="lg"

View file

@ -7240,7 +7240,7 @@ clone-deep@^4.0.1:
kind-of "^6.0.2" kind-of "^6.0.2"
shallow-clone "^3.0.0" shallow-clone "^3.0.0"
clsx@^1.1.1: clsx@^1.0.4, clsx@^1.1.1:
version "1.1.1" version "1.1.1"
resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.1.1.tgz#98b3134f9abbdf23b2663491ace13c5c03a73188" resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.1.1.tgz#98b3134f9abbdf23b2663491ace13c5c03a73188"
integrity sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA== integrity sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA==
@ -8293,6 +8293,14 @@ dom-helpers@^5.0.1:
"@babel/runtime" "^7.8.7" "@babel/runtime" "^7.8.7"
csstype "^2.6.7" csstype "^2.6.7"
dom-helpers@^5.1.3:
version "5.2.0"
resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-5.2.0.tgz#57fd054c5f8f34c52a3eeffdb7e7e93cd357d95b"
integrity sha512-Ru5o9+V8CpunKnz5LGgWXkmrH/20cGKwcHwS4m73zIvs54CN9epEmT/HLqFJW3kXpakAFkEdzgy1hzlJe3E4OQ==
dependencies:
"@babel/runtime" "^7.8.7"
csstype "^3.0.2"
dom-serializer@0: dom-serializer@0:
version "0.2.2" version "0.2.2"
resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.2.2.tgz#1afb81f533717175d478655debc5e332d9f9bb51" resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.2.2.tgz#1afb81f533717175d478655debc5e332d9f9bb51"
@ -15362,6 +15370,18 @@ react-transition-group@^4.3.0:
loose-envify "^1.4.0" loose-envify "^1.4.0"
prop-types "^15.6.2" prop-types "^15.6.2"
react-virtualized@^9.22.2:
version "9.22.2"
resolved "https://registry.yarnpkg.com/react-virtualized/-/react-virtualized-9.22.2.tgz#217a870bad91e5438f46f01a009e1d8ce1060a5a"
integrity sha512-5j4h4FhxTdOpBKtePSs1yk6LDNT4oGtUwjT7Nkh61Z8vv3fTG/XeOf8J4li1AYaexOwTXnw0HFVxsV0GBUqwRw==
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@^16.13.1, react@^16.8.3: react@^16.13.1, react@^16.8.3:
version "16.13.1" version "16.13.1"
resolved "https://registry.yarnpkg.com/react/-/react-16.13.1.tgz#2e818822f1a9743122c063d6410d85c1e3afe48e" resolved "https://registry.yarnpkg.com/react/-/react-16.13.1.tgz#2e818822f1a9743122c063d6410d85c1e3afe48e"