前言
之前遇到不分页直接获取到全部数据,前端滚动查看数据,页面就听卡顿的,当然这和电脑浏览器性能啥的还是有点关系。但根源还是一次性渲染数据过多导致的,因此就想到解决这个问题,最常见就是虚拟滚动,实现只渲染当前可见的部分,这样浏览器一次性渲染的数据少了。
本文介绍虚拟列表和虚拟Table的实现,基于React + ts技术栈。
虚拟列表
虚拟列表通过仅渲染当前可见区域的列表项来解决这个问题。它利用浏览器的滚动事件,根据用户可见区域的大小和滚动位置动态地计算应该渲染哪些列表项。这样,即使数据量很大,也只有当前可见的列表项会被渲染,大大减少了DOM元素的数量,提高了页面性能和响应性。
结合下图想象一下

实现虚拟列表的方法主要涉及以下步骤:
-
计算可见区域:根据容器的尺寸(假如500px)和每一项的高度(50px),计算出可见的列表项数量。然后可视的数据就是10个。
-
监听滚动事件:在容器上添加滚动事件监听,以便实时获取滚动位置。为了容器可滚动,需要在容器内添加空的带有高度的元素,将父元素撑开,然后可滚动。获取scrollTop的高度,就能计算出当前显示第一项的下标(scrollTop / itemHeight),动态更新数据。
基于上面的思路,封装一个滚动列表组件。
import _ from "lodash";
import React, {
useEffect, useState } from "react";
import {
listData } from "./data";
type ListType = {
itemHeight?: number; // 每一项的高度
visibleHeight?: number; // 可见高度
total?: number; // 数据总数
dataSource?: any[]; // 全部数据
};
// 为了看效果我模拟的数据
const myList = Array.from(Array(1000), (item, index) => ({
name: `名字${
item}`, id: index}));
const List = (props: ListType) => {
const {
itemHeight = 54,
visibleHeight = 540,
total = 130,
dataSource = myList,
} = props;
const [showData, setShowData] = useState<any>([]);
const [offset, setOffset] = useState<any>({
top: 0, bottom: 0 });
const visibleCount = Math.ceil(visibleHeight / itemHeight);
useEffect(() => {
const list = _.slice(dataSource, 0, visibleCount);
const bottom =

文章介绍了如何使用React和typescript实现虚拟滚动,以解决一次性渲染大量数据导致的页面卡顿问题。通过虚拟列表和虚拟Table,只渲染当前可见部分,减少DOM元素,提高页面性能。文中提供了具体的代码示例,包括计算可见区域、监听滚动事件和动态更新数据的方法。
最低0.47元/天 解锁文章

7522

被折叠的 条评论
为什么被折叠?



