【发布时间】:2021-05-25 16:40:31
【问题描述】:
我有一个 Recharts 用例,我渲染了超过 20,000 个数据点,这会导致渲染阻塞:
(CodeSandbox 有一个小的脉冲动画,因此在创建新图表数据时更容易看到阻塞渲染。)
在使用开发工具测量性能时,很明显造成这种情况的原因不是浏览器的painting 或rendering 活动,而是Recharts 的scripting 活动:
我不想在这里责怪 Recharts,20k 点很多,但是有没有人知道是否有解决阻塞渲染的方法?
我尝试过的事情:
1.) 增量加载
以增量方式加载更多数据(例如 2k + 2k + 2k + ... = 20k),这只会导致更多、更小的渲染阻塞时间。
2.) 渲染前加载动画
在渲染组件中添加了一个小布尔状态来跟踪“已安装”状态,这至少会在图表组件安装时显示加载动画,因此用户无需等待空白页面/路由切换:
const [showLoading, setShowLoading] = useState<boolean>(true);
const { isLoading, data } = useXY() // remote data fetching
const [isMounted, setIsMounted] = useState(false);
useEffect(() => {
setIsMounted(true);
}, []);
useEffect(() => {
setShowLoading(isLoading || !isMounted);
}, [isLoading, isMounted]);
...
if (showLoading) return <LoadingAnimation />
return <div>...chart...</div>
图表代码: (查看 CodeSandbox 获取完整代码)
function Chart({ data }: { data: Data }) {
console.log("⌛ Rendering chart");
const lineData = useMemo(() => {
return data.lines;
}, [data.lines]);
const areaData = useMemo(() => {
return data.areas;
}, [data.areas]);
return (
<ComposedChart
width={500}
height={400}
margin={{
top: 20,
right: 20,
bottom: 20,
left: 20
}}
>
<CartesianGrid stroke="#f5f5f5" />
<XAxis dataKey="ts" type="number" />
<YAxis />
<Tooltip />
{areaData.map((area) => (
<Area
// @ts-ignore
data={area.data}
dataKey="value"
isAnimationActive={false}
key={area.id}
type="monotone"
fill="#8884d8"
stroke="#8884d8"
/>
))}
{lineData.map((line) => (
<Line
data={line.data}
dataKey="value"
isAnimationActive={false}
key={line.id}
type="monotone"
stroke="#ff7300"
/>
))}
</ComposedChart>
);
}
【问题讨论】:
标签: javascript reactjs typescript performance recharts