前言
在前端开发中,虚拟列表是一个常用的技术,它可以提高列表的性能,减少页面的卡顿。本文将介绍如何在 React SPA 应用中实现虚拟列表加载优化。
虚拟列表的原理
虚拟列表是指当列表中的数据过多时,只渲染可见区域内的数据,而不是渲染整个列表。这样可以减少 DOM 元素的数量,提高页面的性能。
虚拟列表的实现原理是通过计算可见区域的起始索引和结束索引,只渲染这个范围内的数据。当用户滚动列表时,根据滚动位置动态计算可见区域的起始索引和结束索引,然后重新渲染这个范围内的数据。
实现虚拟列表的步骤
步骤一:计算可见区域的起始索引和结束索引
首先,需要计算可见区域的起始索引和结束索引。这个可以通过浏览器的 API scrollTop
和 clientHeight
来计算。
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 的 memo
和 useCallback
来避免不必要的渲染。
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 的 memo
和 useCallback
来避免不必要的渲染和函数重新创建。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/658e7940eb4cecbf2d45c58b