react-virtual vs react-virtualized vs react-window
React 大型列表虚拟化方案对比
react-virtualreact-virtualizedreact-window类似的npm包:

React 大型列表虚拟化方案对比

react-virtualized、react-window 和 react-virtual 都是为了解决 React 应用中渲染大量列表数据时的性能问题而设计的库。它们通过“虚拟化”技术,只渲染用户可见区域的 DOM 节点,从而大幅降低内存占用和渲染时间。react-virtualized 是早期的标准方案,功能全面但较重;react-window 是其继任者,更轻量且专注;react-virtual 则提供了基于 Hook 的无头(headless)方案,灵活性最高。

npm下载趋势

3 年

GitHub Stars 排名

统计详情

npm包名称
下载量
Stars
大小
Issues
发布时间
License
react-virtual07,113158 kB115-MIT
react-virtualized027,0712.24 MB02 年前MIT
react-window017,207216 kB114 天前MIT

React 大型列表虚拟化:react-virtualized vs react-window vs react-virtual

在 React 开发中,当需要渲染成千上万条数据时,直接渲染会导致页面卡顿甚至崩溃。这三个库都通过“虚拟化”技术解决了这个问题 —— 它们只渲染用户可见区域内的元素,其余部分用占位符代替。虽然目标一致,但它们的设计理念和适用场景却有明显差异。

🏗️ 核心架构:组件封装 vs 逻辑钩子

这三个库最大的区别在于它们如何暴露虚拟化逻辑给开发者。

react-virtualized 提供了一整套封装好的组件。

  • 你直接使用 <List>、<Grid> 或 <Table> 组件。
  • 内部逻辑被隐藏,你只需传递配置项。
  • 适合快速搭建,但定制性受限。
// react-virtualized: 使用封装组件
import { List } from 'react-virtualized';

<List
  width={600}
  height={400}
  rowCount={1000}
  rowHeight={50}
  rowRenderer={({ index, style }) => (
    <div style={style}>Row {index}</div>
  )}
/>

react-window 提供了更轻量的组件,但要求你通过渲染属性(Render Props)提供内容。

  • 组件只负责计算可见区域和样式。
  • 你负责渲染具体的 DOM 结构。
  • 平衡了易用性和灵活性。
// react-window: 使用渲染属性
import { FixedSizeList } from 'react-window';

<FixedSizeList
  height={400}
  width={600}
  itemCount={1000}
  itemSize={50}
>
  {({ index, style }) => (
    <div style={style}>Row {index}</div>
  )}
</FixedSizeList>

react-virtual 不提供 UI 组件,只提供一个 Hook。

  • 你调用 useVirtual 获取虚拟化数据。
  • 你需要自己创建滚动容器和映射列表。
  • 灵活性最高,完全无头(headless)。
// react-virtual: 使用 Hook
import { useVirtual } from 'react-virtual';
import { useRef } from 'react';

function VirtualList() {
  const parentRef = useRef();
  const virtualizer = useVirtual({
    size: 1000,
    parentRef,
    estimateSize: () => 50,
  });

  return (
    <div ref={parentRef} style={{ height: 400, overflow: 'auto' }}>
      <div style={{ height: virtualizer.getTotalSize() }}>
        {virtualizer.virtualItems.map(item => (
          <div
            key={item.key}
            style={{
              position: 'absolute',
              top: 0,
              transform: `translateY(${item.start}px)`,
              height: item.size,
            }}
          >
            Row {item.index}
          </div>
        ))}
      </div>
    </div>
  );
}

🎨 样式与布局控制

在处理非标准布局时,这三个库的表现截然不同。

react-virtualized 强制使用绝对定位。

  • 内部样式逻辑固定,难以覆盖。
  • 如果需要使用 Flexbox 或 Grid 布局内部元素,会遇到困难。
  • 适合标准列表,不适合复杂卡片布局。
// react-virtualized: 样式由库控制
// rowRenderer 接收的 style 包含 position: absolute
rowRenderer={({ index, style }) => (
  <div style={style}> {/* 难以修改定位方式 */} </div>
)}

react-window 同样使用绝对定位,但结构更清晰。

  • 你可以通过 outerRef 和 innerRef 访问容器。
  • 虽然定位方式固定,但内容区域完全由你控制。
  • 适合需要自定义滚动条样式的场景。
// react-window: 内容区域可控
<FixedSizeList
  innerElementType="ul" // 可以将内部容器改为 ul
>
  {({ index, style }) => (
    <li style={style}>Item {index}</li>
  )}
</FixedSizeList>

react-virtual 让你手动应用样式。

  • 你拿到 start 和 size 数据,自己决定怎么写样式。
  • 可以轻松切换为 Grid 布局或混合布局。
  • 适合需要高度定制视觉效果的场景。
// react-virtual: 手动应用样式
<div
  style={{
    position: 'absolute',
    top: 0,
    left: 0,
    transform: `translate3d(0, ${item.start}px, 0)`,
  }}
>
  {item.index}
</div>

🔄 维护状态与生态建议

选择库时,维护状态是一个关键因素,它关系到未来的升级成本和安全性。

react-virtualized 已进入维护模式。

  • 作者建议新项目使用 react-window。
  • 修复 Bug 的速度较慢,主要支持现有用户。
  • 如果新项目没有特殊理由,不建议选用。

react-window 处于稳定维护期。

  • 由 React 核心团队成员维护,可靠性高。
  • API 稳定,很少破坏性更新。
  • 是大多数通用场景的默认推荐。

react-virtual 活跃开发中。

  • 属于 TanStack 生态系统,更新频繁。
  • 紧跟 React 新特性(如并发模式)。
  • 适合喜欢尝试新技术和需要深度定制的团队。

📊 核心特性对比表

特性react-virtualizedreact-windowreact-virtual
API 类型封装组件 (Class)轻量组件 (Render Props)Hook (无头)
DOM 控制低 (固定结构)中 (内容可控)高 (完全手动)
布局方式绝对定位绝对定位手动控制 (绝对/相对)
维护状态维护模式 (Legacy)稳定维护活跃开发
学习曲线中 (配置项多)低 (直观)高 (需理解原理)

💡 最终建议

react-virtualized 就像一台重型机床 🏭—— 功能强大但笨重,适合旧项目维护。如果你的代码库已经大量使用它,迁移成本可能高于收益,可以暂时保留。但在新项目中,它不再是首选。

react-window 就像一把标准电钻 🔩—— 轻便、可靠、适合大多数任务。如果你只需要渲染标准的长列表或网格,不需要复杂的自定义布局,选它最稳妥。它的 API 设计合理,文档完善,能满足 90% 的需求。

react-virtual 就像一套精密的手工工具 🛠️—— 灵活、强大,但需要更多技巧。如果你需要实现非标准的滚动效果、动态高度计算或与现有布局系统深度集成,它的 Hook 设计能给你最大自由。适合对性能和控制力有极致要求的团队。

总结:对于大多数新项目,优先选择 react-window。如果需要极致灵活性或正在使用 TanStack 生态,选择 react-virtual。尽量避免在新项目中引入 react-virtualized。

如何选择: react-virtual vs react-virtualized vs react-window

  • react-virtual:

    如果你需要极高的灵活性,希望完全控制 DOM 结构,或者正在使用 TanStack 生态系统,react-virtual 是理想方案。它基于 Hook 设计,无头(headless)特性让你可以自由组合样式和布局,非常适合需要定制化滚动行为或复杂布局的场景。

  • react-virtualized:

    如果你的项目是旧代码库维护,且已经深度依赖 react-virtualized 的复杂组件(如 Table 或 Grid),继续使用它可以避免大规模重构。但在新项目中不建议选用,因为它主要基于 Class 组件,API 较重,且官方已建议转向更轻量的方案。

  • react-window:

    如果你需要快速实现标准的长列表或网格,且希望拥有稳定的维护和较小的包体积,react-window 是最佳选择。它由 react-virtualized 的同一作者开发,专为现代 React 优化,API 简洁,适合大多数通用的虚拟化场景。

react-virtual的README

Table of Contents generated with DocToc

React Virtual Header

Hooks for virtualizing scrollable elements in React

#TanStack Join the community on Spectrum

Enjoy this library? Try the entire TanStack! React Query, React Table, React Charts, React Form

Visit react-virtual.tanstack.com for docs, guides, API and more!

Quick Features

  • Row, Column, and Grid virtualization
  • One single headless hook
  • Fixed, variable and dynamic measurement modes
  • Imperative scrollTo control for offset, indices and alignment
  • Custom scrolling function support (eg. smooth scroll)