【发布时间】:2021-11-25 14:34:46
【问题描述】:
我有一个使用 React、Gatsby 和 Chakra UI 框架的简单网络应用程序。该应用程序包含一个索引页面,该页面从 1000 多个 mdx 文件中查询 frontmatter,并呈现一个最小的摘要组件,其中包含来自 frontmatter 的 5 个字段和一个指向每个详细页面的链接。 1000 多个详细信息页面是在 gatsby-node.js 中使用 createPage 生成的。
索引页面使用 map 遍历每个 mdx 节点,并使用 Chakra UI 简单网格以及每个项目的其他一些 Chakra 组件。
应用部署到 Gatsby Cloud 时收到的灯塔报告将应用的性能评为 60/100,这主要是由于 DOM 中的元素过多(索引页面呈现的 1000 多个摘要元素)。
我已经查看了所有相关文档并在其他来源中搜索了 SO,但找不到可行的解决方案来仅渲染 html 以在任何给定点显示在屏幕上的 25 个左右项目并根据需要渲染其余部分而不是从一开始就渲染所有 1000+。
import * as React from "react";
import { ChakraProvider, chakra, Box, SimpleGrid, HStack, Button, VStack, Wrap, WrapItem, Badge } from "@chakra-ui/react";
import { graphql, useStaticQuery } from 'gatsby';
const IndexPage = () => {
const query = useStaticQuery(graphql`
query AllObjects {
allMdx(sort: {fields: frontmatter___field1}) {
nodes {
frontmatter {
field1
field2
field3
field4
field5
field6
field7
uniqueId
}
}
}
}
`)
return (
<ChakraProvider>
<body>
<main>
<SimpleGrid columns={{base: 1, lg: 3, md: 2, sm:1}} spacing={{base: '1.5em', lg: '1.5em', md:'1.0', sm:'0.90em'}}>
{ query.allMdx.nodes.map((node) => (
<Box key={node.frontmatter.field1} margin="2em" padding="1em">
<HStack padding="0.4em" align="center" alignItems="stretch" justifyContent="space-between">
<Button size="sm" shadow="md" colorScheme="blue"
onClick={(e) => {
e.preventDefault();
window.location.href=`/objects/${node.frontmatter.field1.toLowerCase()}`;
}}
>Detail</Button>
<Box align="center"/>
<VStack alignItems="end" justifyContent="right">
<Wrap columns={2} spacing={1} direction={["row-reverse"]} isInline="true" shouldWrapChildren="true">
<WrapItem>
{node.frontmatter.field5 === true &&
<Badge colorScheme="green">Field5</Badge>
}
</WrapItem>
<WrapItem>
{node.frontmatter.field6 === true &&
<Badge colorScheme="blue">Field6</Badge>
}
</WrapItem>
<WrapItem>
{node.frontmatter.field7 === true &&
<Badge colorScheme="orange">field7</Badge>
}
</WrapItem>
<WrapItem>
{node.frontmatter.field4 === true &&
<Badge colorScheme="red">Field8</Badge>
}
</WrapItem>
</Wrap>
</VStack>
</HStack>
<Box bg="gray.300" borderRadius="0.5em" margin="0em" padding="0em">
<chakra.h2 id={node.frontmatter.field1.toLowerCase()}>
Field1: {node.frontmatter.field1}
</chakra.h2>
<chakra.p>Field2: {node.frontmatter.field2}</chakra.p>
<chakra.p>{node.frontmatter.field3}</chakra.p>
</Box>
</Box>
))}
</SimpleGrid>
</main>
</body>
</ChakraProvider>
)
};
export default IndexPage;
【问题讨论】: