React SPA 应用中如何实现虚拟列表加载优化

前言

在前端开发中,虚拟列表是一个常用的技术,它可以提高列表的性能,减少页面的卡顿。本文将介绍如何在 React SPA 应用中实现虚拟列表加载优化。

虚拟列表的原理

虚拟列表是指当列表中的数据过多时,只渲染可见区域内的数据,而不是渲染整个列表。这样可以减少 DOM 元素的数量,提高页面的性能。

虚拟列表的实现原理是通过计算可见区域的起始索引和结束索引,只渲染这个范围内的数据。当用户滚动列表时,根据滚动位置动态计算可见区域的起始索引和结束索引,然后重新渲染这个范围内的数据。

实现虚拟列表的步骤

步骤一:计算可见区域的起始索引和结束索引

首先,需要计算可见区域的起始索引和结束索引。这个可以通过浏览器的 API scrollTopclientHeight 来计算。

const startIndex = Math.floor(scrollTop / rowHeight);
const endIndex = Math.min(
  startIndex + Math.ceil(clientHeight / rowHeight),
  data.length - 1
);

其中,scrollTop 表示滚动区域距离顶部的距离,clientHeight 表示可见区域的高度,rowHeight 表示每一行的高度,data 表示列表的数据。

步骤二:渲染可见区域的数据

然后,根据起始索引和结束索引,渲染可见区域的数据。这个可以通过 Array.prototype.slice() 方法来获取可见区域的数据。

const visibleData = data.slice(startIndex, endIndex + 1);

步骤三:优化渲染性能

最后,为了优化渲染性能,可以使用 React 的 memouseCallback 来避免不必要的渲染。

const Row = memo(({ index, style }) => {
  const row = data[index];
  return <div style={style}>{row}</div>;
});

const renderRow = useCallback(({ index, style }) => {
  return <Row index={index} style={style} />;
}, []);

return (
  <List
    height={height}
    itemCount={visibleData.length}
    itemSize={rowHeight}
    overscanCount={10}
    renderItem={renderRow}
  />
);

其中,memo 可以避免不必要的渲染,useCallback 可以避免不必要的函数重新创建。

示例代码

import { memo, useCallback, useState } from "react";
import { FixedSizeList as List } from "react-window";

const data = Array.from({ length: 1000 }, (_, index) => `Row ${index}`);

const rowHeight = 30;

export default function App() {
  const [scrollTop, setScrollTop] = useState(0);
  const [clientHeight, setClientHeight] = useState(0);

  const startIndex = Math.floor(scrollTop / rowHeight);
  const endIndex = Math.min(
    startIndex + Math.ceil(clientHeight / rowHeight),
    data.length - 1
  );

  const visibleData = data.slice(startIndex, endIndex + 1);

  const Row = memo(({ index, style }) => {
    const row = data[index];
    return <div style={style}>{row}</div>;
  });

  const renderRow = useCallback(({ index, style }) => {
    return <Row index={index} style={style} />;
  }, []);

  return (
    <div
      style={{ height: "100vh", overflow: "auto" }}
      onScroll={(event) => {
        setScrollTop(event.target.scrollTop);
      }}
      ref={(element) => {
        setClientHeight(element?.clientHeight || 0);
      }}
    >
      <List
        height={clientHeight}
        itemCount={visibleData.length}
        itemSize={rowHeight}
        overscanCount={10}
        renderItem={renderRow}
      />
    </div>
  );
}

总结

在 React SPA 应用中实现虚拟列表加载优化,可以提高列表的性能,减少页面的卡顿。实现虚拟列表的步骤包括计算可见区域的起始索引和结束索引、渲染可见区域的数据、优化渲染性能。在实现时,可以使用 React 的 memouseCallback 来避免不必要的渲染和函数重新创建。

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/658e7940eb4cecbf2d45c58b


纠错
反馈