在 React 中渲染大型数据集的 3 种方法

news2024/11/24 10:52:04

随着 Web 应用程序变得越来越复杂,我们需要找到有效的方法来优化性能和渲染大型数据集。在 React 应用程序中处理大型数据集时,一次呈现所有数据可能会导致性能不佳和加载时间变慢。

虚拟化是一种通过一次仅呈现数据集的一部分来解决此问题的技术,从而为用户提供更快、更流畅的体验。在本文中,我们将探讨和比较可用于 React 的各种虚拟化列表库的优缺点,包括:

  • React Virtuoso

  • React Window

  • react-infinite-scroller

React Virtuoso

React Virtuoso 是 React 的虚拟化列表库,可以快速高效地渲染大型数据集。它是高度可定制的,我们可以使用它来渲染简单和复杂的数据结构。

React Virtuoso 使用窗口技术,仅渲染屏幕上可见的元素,从而缩短加载时间和提高性能。

下面介绍如何通过两个步骤在您的应用程序中使用 React Virtuoso

首先,安装 Virtuoso 库:

npm install react-virtuoso

接下来,在应用程序中使用该组件:

import * as React from 'react'
import * as ReactDOM from 'react-dom'
import { Virtuoso } from 'react-virtuoso'
const App = () => (
  <Virtuoso
    style={{ height: '600px',
    background: '#f8f8f8'
   }}
    totalCount={10000}
    itemContent={index => (
      <div style={{ 
        background: index % 2 === 0 ? '#ffbb00' : '#ffcc33',
        color: '#333',
        padding: '10px',
        fontSize: '16px',
        fontFamily: 'Arial, sans-serif',
        border: '1px solid #ccc',
        borderRadius: '4px',
        margin: '5px 0'
      }}>
        Item {index}
      </div>
    )}
  />
)
export default App;
ReactDOM.render(<App />, document.getElementById('root'))

在上面的代码中,我们从 react-virtuoso 库中导入 Virtuoso 组件。

接下来,我们定义一个名为 返回 App 组件的功能 Virtuoso 组件。

该 Virtuoso 组件包含多个道具:

  • style :设置组件的样式,包括其高度和背景颜色

  • totalCount :设置列表中的项目总数;在这种情况下,10,000

  • itemContent :接收一个 index 参数并返回用于在该索引处呈现项目的 JSX 代码

在这种情况下,该函数呈现一个 div 包含文本“Item”的元素,后跟索引号。该 prop 根据 style 索引是奇数还是偶数来设置 div 元素的背景颜色、字体大小、字体系列、边框、边框半径和边距。

下面是我们代码的结果:

图片

我们也可以将图像添加到列表中:

import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { Virtuoso } from 'react-virtuoso';
const App = () => {
  const [images, setImages] = React.useState([]);
  // Fetch random images from Unsplash on component mount
  React.useEffect(() => {
    const fetchImages = async () => {
      const response = await fetch(
        'https://api.unsplash.com/photos/random?count=100',
        {
          headers: {
            Authorization: 'Client-ID <UNSPLASH ACCESS KEY>',
          },
        }
      );
      const data = await response.json();
      const urls = data.map(item => item.urls.thumb);
      setImages(urls);
    };
    fetchImages();
  }, []);
  return (
    <Virtuoso
      style={{ 
        height: '400px',
        background: '#f8f8f8'
      }}
      totalCount={10000}
      itemContent={index => (
        <div style={{ 
          background: index % 2 === 0 ? '#ffbb00' : '#ffcc33',
          color: '#333',
          padding: '10px',
          fontSize: '16px',
          fontFamily: 'Arial, sans-serif',
          border: '1px solid #ccc',
          borderRadius: '4px',
          margin: '5px 0',
          display: 'flex',
          alignItems: 'center'
        }}>
          <img src={images[index % 100]} alt={`Item ${index}`} style={{ marginRight: '10px', width: '50px', height: '50px', borderRadius: '50%' }} />
          Item {index}
        </div>
      )}
    />
  );
};
export default App;
ReactDOM.render(<App />, document.getElementById('root'));

您可能会注意到,此代码与我们以前的代码没有太大区别。我们使用 useState 和useEffect钩子定义一个功能组件 App 。然后,我们声明一个调用 images 的状态变量,并使用 Hook  useState 将其初始值设置为空数组。

我们定义了一个调用 fetchImages 的函数,该函数使用 API 向 Unsplash fetch API 发出 GET 请求以检索 100 张随机图像。然后,我们映射响应数据并提取每个图像的 thumb URL,并使用函数 setImages 将 images 状态变量设置为生成的 URL 数组。

接下来,我们使用 Hook 在 useEffect 组件挂载时调用该 fetchImages 函数一次,因为我们只想获取一次图像。像以前一样,我们返回一个 Virtuoso 组件,该组件包含以下 props

  • style:设置为为我们的 Virtuoso 组件创建背景颜色和高度, height 其属性为 和 400px 背景属性 #f8f8f8

  • totalCount

  • itemContent

这一次,我们从 itemContent 函数返回的 JSX 代码是一个 div 包含元素 img 和一些文本的元素。元素 img  的src属性设置为与当前 index 值对应的图像的 URL,该 URL 使用取模运算符 ( ) 从 images 状态变量中检索。

图片

Virtuoso 的优点

  • Virtuoso在渲染大型数据集方面非常有效

  • 它是高度可定制的

  • 它提供对动态项目大小的支持

  • 好的性能表现

Virtuoso 的缺点

  • 有限的文档

  • 不支持嵌套列表

React Window

我们要看的下一个库是 React Window,这是一个用于 React 的虚拟化列表库,它使用与 React Virtuoso 相同的窗口技术。

React Window 是 React Virtualized 的更新版本。它还具有高性能,可用于高效渲染大型数据集。React Window 为我们提供了一组 API,我们可以使用它们来自定义列表的行为,使其成为一个灵活而强大的工具。

安装React Window 

npm install --save react-window

为了演示它是如何工作的,我们将使用 Faker 库来生成大型数据集。Faker 是一个生成虚假数据的库,例如姓名、地址和电话号码。

使用 npm 安装伪造程序库:

npm install faker

然后在代码中实现它:

import React from 'react';
import { FixedSizeList } from 'react-window';
import { faker } from '@faker-js/faker';
const App = () => {
  const data = Array.from({ length: 10000 }).map(() => ({
    name: faker.name.firstName(),
    email: faker.internet.email(),
  }));
  const Row = ({ index, style }) => {
    const isEvenRow = index % 2 === 0;
    const backgroundColor = isEvenRow ? '#F9A03F' : '#FDDB3A';
    const textColor = isEvenRow ? '#FFFFFF' : '#4A4A4A';
    const rowStyle = {
      ...style,
      backgroundColor,
      color: textColor,
      display: 'flex',
      justifyContent: 'space-between',
      alignItems: 'center',
      padding: '0 16px',
    };
    return (
      <div style={rowStyle}>
        <p>{data[index].name}</p>
        <p>{data[index].email}</p>
      </div>
    );
  };
  return (
    <FixedSizeList height={600} width={1200} itemSize={50} itemCount={data.length}>
      {Row}
    </FixedSizeList>
  );
};
export default App;

我们从 react-window 库中导入 FixedSizeList 组件,以及用于生成 faker 用于测试目的的假数据的库。

导入必要的库后,我们定义一个名为的功能组件,该组件 App 创建一个包含 10,000 个对象的数组。每个对象都包含一个 name 和一个email属性;它们的值是使用 faker 库生成的。

接下来,我们定义一个名为 Row 的新功能组件,它接受 index 和 style prop 并呈现每一行数据。它从我们之前定义的 data 数组中检索相应索引的 name 和email 数据,并使用传入 style 的prop将其呈现在 div 元素中。

最后,我们从 react-window 库中返回一个 FixedSizeList 组件,该组件包含以下内容:

  • height 和 width 道具,决定列表的大小

  • itemSize:用于设置每行的高度

  • itemCount:用于设置列表中的项目总数

  • 一个呈现每行数据的函数,该函数设置为我们之前定义的 Row 组件

图片

我们可以使用以下 VariableSizedList 组件创建可变大小的列表:

import React from 'react';
import { VariableSizeList } from 'react-window';
import { faker } from '@faker-js/faker';
const App = () => {
  const data = Array.from({ length: 10000 }).map(() => ({
    name: faker.name.firstName(),
    email: faker.internet.email(),
  }));
  const Row = ({ index, style }) => {
    const isEvenRow = index % 2 === 0;
    const backgroundColor = isEvenRow ? '#F9A03F' : '#FDDB3A';
    const textColor = isEvenRow ? '#FFFFFF' : '#4A4A4A';
    const rowStyle = {
      ...style,
      backgroundColor,
      color: textColor,
      display: 'flex',
      justifyContent: 'space-between',
      alignItems: 'center',
      padding: '0 16px',
    };
    return (
      <div style={rowStyle}>
        <p>{data[index].name}</p>
        <p>{data[index].email}</p>
      </div>
    );
  };
  const getItemSize = index => {
    const randomHeight = Math.floor(Math.random() * 100) + 50;
    return randomHeight;
  };
  return (
    <VariableSizeList height={600} width={1200} itemCount={data.length} itemSize={getItemSize}>
      {Row}
    </VariableSizeList>
  );
};
export default App;

图片

在此示例中,该 getItemSize 函数计算每行 50–150 像素之间的随机高度。您可以调整计算以生成不同的大小范围,甚至可以根据每行中的数据生成不同的大小。

请注意,由于行高变化非常大,滚动性能可能会受到影响,因为列表组件必须在滚动时计算和定位每一行。

React Window的优点

  • 高性能

  • 定制

  • 支持动态项目大小

  • 良好的文档

React Window的缺点

  • 对嵌套列表的支持有限

  • 没有对滚动恢复的内置支持

react-infinite-scroller

react-infinite-scroller 是一个库,允许您以高性能方式呈现大型数据集。该库还使用窗口化或虚拟化技术,其中仅呈现数据的可见部分,其余部分在用户滚动时按需加载。

我们也将使用 Faker 库来生成大型数据集。安装它:

npm install faker

然后安装 react-infinite-scroller :

npm i react-infinite-scroller

接下来,我们将创建一个名为的组件 UserList ,该组件呈现由Faker库生成的用户列表。

import React, { useState } from "react";
import InfiniteScroll from "react-infinite-scroller";
import { faker } from "@faker-js/faker";
function UserList() {
  const [users, setUsers] = useState([]);
  const loadMore = (page) => {
    const newUsers = [];
    for (let i = 0; i < 20; i++) {
      newUsers.push({
        name: faker.name.findName(),
        email: faker.internet.email(),
        phone: faker.phone.phoneNumber(),
      });
    }
    setUsers([...users, ...newUsers]);
  };
  const rowStyle = {
    display: "flex",
    justifyContent: "space-between",
    alignItems: "center",
    padding: "10px",
    backgroundColor: "#f1f1f1",
    borderBottom: "1px solid #ccc",
    fontSize: "16px",
    color: "#333",
  };
  const nameStyle = {
    fontWeight: "bold",
    color: "#38a3a5",
  };
  const emailStyle = {
    fontStyle: "italic",
    color: "#ff7f50",
  };
  const phoneStyle = {
    color: "#6a5acd",
  };
  return (
    <InfiniteScroll
      pageStart={0}
      loadMore={loadMore}
      hasMore={true}
      loader={<div className="loader" key={0}>Loading ...</div>}
    >
      <ul style={{ listStyle: "none", margin: "0", padding: "0" }}>
        {users.map((user, index) => (
          <li key={index} style={rowStyle}>
            <div style={nameStyle}>{user.name}</div>
            <div style={emailStyle}>{user.email}</div>
            <div style={phoneStyle}>{user.phone}</div>
          </li>
        ))}
      </ul>
    </InfiniteScroll>
  );
}
export default UserList;

图片

让我们分解一下。在组件中 UserList ,我们使用 useState Hook 来管理 users 数组的状态。该loadMore函数生成 20 个新用户并将其追加到现有 users 数组中。

装载组件时,将呈现 InfiniteScroll 组件。 pageStart prop 指示将从何处加载数据的页码。

loadMore prop 是一个回调函数,当用户滚动到列表末尾时调用。它接收页码作为参数,可用于从服务器加载数据。在我们的例子中,我们使用Faker库生成虚假数据。

hasMore prop 指示是否有更多数据要加载。在我们的例子中,我们希望将其设置为 true ,因为我们想无限期地加载更多数据。 loader prop 是一个 React 元素,在加载数据时呈现。我们添加了一个简单的加载器,用于显示加载消息。

最后,我们使用该方法map呈现用户列表。每个用户都呈现在一个 li 元素中,并显示每个用户的姓名、电子邮件和电话号码。

对于样式,我们使用 JavaScript 对象定义几种样式,并使用 style 属性将它们应用于相应的元素。该 rowStyle 对象应用浅灰色背景色,具有深灰色边框和白色文本颜色,而 nameStyle 、 emailStyle 和对象分别为姓名、电子邮件和电话号码字段定义不同的文本颜色和 phoneStyle 样式。

使用 react-infinite-scroller 的优点

  • 改进的性能:使用反应无限滚动器的主要优点是其改进的性能。通过仅渲染数据的可见部分,它减少了 DOM 节点的数量,从而提高了渲染速度

  • 减少内存消耗:由于仅呈现数据的可见部分,因此显着减少了内存消耗

  • 无限滚动:库提供开箱即用的无限滚动,这意味着数据可以动态加载,无需页面刷新或手动加载

  • 易于使用:React-infinite-scroller 易于使用,并与 React 应用程序无缝集成

使用 react-infinite-scroller 缺点

  • 复杂的实现:实现无限滚动可能很复杂,特别是对于初学者。您需要确保以高性能方式加载数据,同时跟踪组件的状态

  • 动态高度问题:反应无限滚动器不能解决动态高度问题。如果列表中的项目具有不同的高度,则库无法准确计算整个列表的高度,从而导致滚动位置不正确

功能集比较表

功能/工具React VirtuosoReact Windowreact-infinite-scroller
性能非常好非常好
API丰富有限有限
虚拟化支持YesYesYes
SSR渲染支持YesYesNo
自定制有限有限
易于使用容易容易容易
面向开发人员的内置功能提供分页和无限加载功能。开发者社区实现了带有Chrome和Firefox扩展的开发者工具GUI。支持将缓存持久化到外部存储位置(即本地存储)。提供分页和无限加载功能。它带有一个官方的开发人员工具GUI,支持缓存操作。支持将缓存持久化到外部存储位置(即本地存储)。N/A
React suspense支持支持N/A
对其他前端库的官方支持否,类似的社区库可用:sswr在进行中,类似的社区库可用:vue-queryN/A

总结

高效渲染大型数据集是 Web 开发的一个关键方面。虚拟化是一种使开发人员能够有效地呈现大型数据集并提高 Web 应用程序性能的技术。

在本文中,我们探讨了可用于 React 的各种虚拟化列表库,包括 React VirtuosoReact Window 和 react-infinite-scroll。每个库都有其优点和缺点,库的选择取决于特定的用例。通过使用这些虚拟化列表库,您可以显著提高 React应用程序的性能并提供更流畅的用户体验。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/825728.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

AIGC产业公司简况列表

最近梳理了国内外AIGC产业链相关的公司列表&#xff0c;如下图所示&#xff1a; 出自&#xff1a;AIGC产业公司简况列表 | 秋天的童话博客

ElementUI el-table 鼠标滚动失灵的问题及解决办法

Bug&#xff1a;ElementUI el-table 鼠标滚轮下滑动失灵的情况 我测出来的这个问题条件很苛刻&#xff0c;需要达到以下几个条件才会触发&#xff1a; 1.element plus&#xff08;其他版本没试&#xff09; 2.el-table-column组件有fixed属性时 3.template标签中有el-butto…

Adobe ColdFusion 反序列化漏洞复现(CVE-2023-29300)

0x01 产品简介 Adobe ColdFusion是美国奥多比&#xff08;Adobe&#xff09;公司的一套快速应用程序开发平台。该平台包括集成开发环境和脚本语言。 0x02 漏洞概述 Adobe ColdFusion存在代码问题漏洞&#xff0c;该漏洞源于受到不受信任数据反序列化漏洞的影响&#xff0c;攻击…

赶快卸载 Navicat和DataGrip吧,阿里又开源了一款数据库神器,太炸了

Chat2DB 是一款有开源免费的多数据库客户端工具&#xff0c;支持windows、mac本地安装&#xff0c;也支持服务器端部署&#xff0c;web网页访问。和传统的数据库客户端软件Navicat、DBeaver 相比Chat2DB集成了AIGC的能力&#xff0c;能够将自然语言转换为SQL&#xff0c;也可以…

eclipse was unable to locate its companion shared library

当转移或者Copy工程时&#xff0c; eclipse was unable to locate its companion shared library eclipse.ini 里面的路径配置错误导致 --launcher.library C:/Users/**/.p2/pool/plugins/org.eclipse.equinox. launcher.win32.win32.x86_64_1.2.700.v20221108-1024 -product …

什么是数字化?数字化转型概念是怎么兴起的?

什么是数字化&#xff1f;数字化转型的概念是怎么兴起的&#xff1f;下面我将分为2部分给大家做详细讲解。 一、什么是数字化&#xff1f; 不同国家和不同行业&#xff0c;似乎对数字化转型有不同的定义。比如&#xff1a; 美国早在2003年就提出了“数字化双胞胎”的概念&…

FuncGPT来了!专注AI生成JAVA函数,五大能力ChatGPT都说好

大语言模型风靡全球&#xff0c;正加速重构各行各业。继 GPT-4 、文心一言等生成式 AI产品之后&#xff0c;代码生成工具的队伍再添新员。近日FuncGPT&#xff08;慧函数&#xff09;功能重磅上线。 作为飞算SoFlu软件机器人的一个重要组成部分&#xff0c;FuncGPT&#xff08;…

Python 程序设计入门(001)—— 安装 Python(Windows 操作系统)

Python 程序设计入门&#xff08;001&#xff09;—— 安装 Python&#xff08;Windows 操作系统&#xff09; 目录 Python 程序设计入门&#xff08;001&#xff09;—— 安装 Python&#xff08;Windows 操作系统&#xff09;一、下载 Python 安装包二、安装 Python三、测试&…

如何在Visual Studio Code中用Mocha对TypeScript进行测试

目录 使用TypeScript编写测试用例 在Visual Studio Code中使用调试器在线调试代码 首先&#xff0c;本文不是一篇介绍有关TypeScript、JavaScript或其它编程语言数据结构和算法的文章。如果你正在准备一场面试&#xff0c;或者学习某一个课程&#xff0c;互联网上可以找到许多…

Java版本工程行业管理系统源码-专业的工程管理软件-提供一站式服务 em

&#xfeff; 工程项目管理软件&#xff08;工程项目管理系统&#xff09;对建设工程项目管理组织建设、项目策划决策、规划设计、施工建设到竣工交付、总结评估、运维运营&#xff0c;全过程、全方位的对项目进行综合管理 工程项目各模块及其功能点清单 一、系统管理 1、数据…

如何开发专属花店小程序

在当今移动互联网时代&#xff0c;小程序已经成为各类企业的必备营销工具之一。对于花店来说&#xff0c;打造一个花店预约小程序&#xff0c;可以帮助提升用户体验&#xff0c;提高销售额。那么&#xff0c;如何从零开始&#xff0c;快速打造一个花店预约小程序呢&#xff1f;…

Vue3 实用的开发技巧

一、前言 Vue3已经发布很长时候了&#xff0c;官方也将默认版本切换到了vue3&#xff0c;Vue官网也发布了完善的中文文档&#xff0c;不知同志们是否已经开始使用了了呢&#xff1f;下面给大家介绍一些在开发中Vue3实用的开发技巧&#xff0c;让大家开发更加流畅。 二、开发技…

Vue实现leafletMap自定义绘制线段 并且删除指定的已绘制的点位

效果&#xff1a;点击表格可实现选中地图点位&#xff0c;删除按钮点击可删除对应点位并且重新绘制线段&#xff0c;点击确定按钮 保存已经绘制的点位信息传给父组件 并且该组件已实现回显 完整的组件代码如下 文件名称为&#xff1a; leafletMakePointYt <!--* Descripti…

小程序学习(六):全局配置

1.全局配置文件及常用的配置项 全局配置-window 2.小程序窗口的组成部分 3.了解window节点常用的配置项 4.设置导航栏的标题 设置步骤:app.json->window->navigationBarTitleText 5.设置导航栏的背景色 背景颜色不支持red这种文字 6.设置导航栏的标题颜色 注意:navigat…

山西电力市场日前价格预测【2023-08-03】

日前价格预测 预测明日&#xff08;2023-08-03&#xff09;山西电力市场全天平均日前电价为344.46元/MWh。其中&#xff0c;最高日前电价为395.01元/MWh&#xff0c;预计出现在19: 45。最低日前电价为314.42元/MWh&#xff0c;预计出现在03: 15。 价差方向预测 1&#xff1a;实…

CefInitialize初始化

结合代码以及查看exe生成目录的debug.log [0802/160846.105:ERROR:icu_util.cc(133)] Invalid file descriptor to ICU data received. setlocal mt.exe -nologo -manifest "D:/D-Pro/Test/t_Explore/t_Explore/lib/Resources/cefsimple.exe.manifest" "D:/D-P…

第一章 基本的图像操作和处理

文章目录 第一章 基本的图像操作和处理1.1PIL&#xff1a;Python图像处理类库1.1.1转图像格式1.1.2创建缩略图1.1.3复制和粘贴图像区域 1.2Matplotlib1.2.1绘制图像、点、线1.2.2图像轮廓和直方图 1.3NumPy1.3.1图像数组表示1.3.2灰度变换1.3.4直方图均衡化 1.4SciPy1.4.1图像模…

基于Yolov2深度学习网络的车辆检测算法matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 4.1. 卷积神经网络&#xff08;CNN&#xff09; 4.2. YOLOv2 网络 4.3. 实现过程 4.4. 应用领域 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 MATLAB2022A 3.部分核心…

USB技术浅析

一、USB3.0 USB是史上定义出的最成功的PC外围互连技术&#xff0c;并且已经迅猛地被引入到CE和Mobile领域。仅仅在2006年&#xff0c;就有超过20亿USB设备出产&#xff0c;而现在已经有超过60亿的USB产品被安装。 而随着技术创新的不断前进&#xff0c;新式设备&#xff0c;媒…

在线考试系统springboot学生试卷问答管理java jsp源代码mysql

本项目为前几天收费帮学妹做的一个项目&#xff0c;Java EE JSP项目&#xff0c;在工作环境中基本使用不到&#xff0c;但是很多学校把这个当作编程入门的项目来做&#xff0c;故分享出本项目供初学者参考。 一、项目描述 在线考试系统springboot 系统有2权限&#xff1a;管理…