【阿里前端面试题】虚拟列表滚动组件开发的原因,以及关键技术点实现

news2024/11/16 21:53:12

大家好,我是“寻找DX3906”。每天进步一点。日积月累,有朝一日定会厚积薄发!
在这里插入图片描述

前言:
前面已经和大家分享阿里的了6篇前端面试题:
《【阿里前端面试题】浏览器的加载渲染过程》
《【阿里前端面试题】客户端和服务器交互,为什么选用tcp协议建立链接?》
《【阿里前端面试题】客户端和服务器交互的过程中,丢包是怎么产生的?》
《【阿里前端面试题】知道了解浏览器渲染对自己有什么帮助?》
《【阿里前端面试题】聊聊前端性能优化的方案,解决过什么样的性能问题?》
《【阿里前端面试题】前端页面懒加载的时间分片为什么能对加载性能优化?》
虚拟列表(Virtual List)是一种性能优化技术,用于渲染长列表,通过只渲染可见的列表项来减少DOM操作和提高性能。以下是使用React开发虚拟列表滚动组件的基本步骤和示例代码:

1. 基本组件结构

首先,定义一个虚拟列表组件,它接收列表数据和其他必要的props。

import React, { useState, useRef, useEffect, useCallback } from 'react';

const VirtualList = ({ itemCount, itemHeight, renderItem, overscanCount = 5 }) => {
  // ...
  return (
    <div className="virtual-list" style={{ height: '300px', overflow: 'auto' }}>
      <div
        className="virtual-list-items"
        style={{ transform: `translateY(${startIndex * itemHeight}px)` }}
      >
        {itemsToRender.map((id) => renderItem(id))}
      </div>
    </div>
  );
};

2. 使用useState和useRef

使用useState来存储当前滚动位置和渲染的列表项范围,使用useRef来引用滚动容器和滚动位置。

const [scrollPos, setScrollPos] = useState(0);
const itemsRef = useRef([]);
const listRef = useRef(null);

3. 计算可见项

根据滚动位置和列表项高度,计算当前应该渲染哪些列表项。

useEffect(() => {
  const list = listRef.current;
  const scrollTop = list.scrollTop;
  const startIndex = Math.floor(scrollTop / itemHeight);
  const endIndex = startIndex + visibleItemCount + overscanCount;
  const itemsToRender = new Array(endIndex - startIndex);

  itemsToRender.forEach((_, index) => {
    itemsToRender[index] = renderItem(startIndex + index);
  });

  setScrollPos(scrollTop);
  itemsRef.current = itemsToRender;
}, [itemCount, itemHeight]);

4. 监听滚动事件

使用useCallback来创建一个处理滚动事件的回调函数,并在组件挂载时添加滚动事件监听器,在卸载时移除。

const handleScroll = useCallback(() => {
  if (listRef.current) {
    const scrollTop = listRef.current.scrollTop;
    setScrollPos(scrollTop);
  }
}, [itemHeight]);

useEffect(() => {
  listRef.current.addEventListener('scroll', handleScroll);
  return () => {
    listRef.current.removeEventListener('scroll', handleScroll);
  };
}, [handleScroll]);

5. 样式和性能优化

确保虚拟列表和滚动容器有适当的CSS样式,使用transform属性来移动列表项,以获得更好的性能。

.virtual-list {
  position: relative;
  width: 100%;
  max-height: 300px;
  overflow: auto;
}

.virtual-list-items {
  position: absolute;
  width: 100%;
  top: 0;
  left: 0;
}

6. 完整的组件示例

将上述代码片段组合成一个完整的虚拟列表组件。

const VirtualList = ({ itemCount, itemHeight, renderItem, overscanCount = 5 }) => {
  const [scrollPos, setScrollPos] = useState(0);
  const itemsRef = useRef([]);
  const listRef = useRef(null);
  const visibleItemCount = 20; // 根据容器高度和项高度计算

  useEffect(() => {
    const list = listRef.current;
    const handleScroll = () => {
      const scrollTop = list.scrollTop;
      const startIndex = Math.floor(scrollTop / itemHeight) - overscanCount;
      const endIndex = startIndex + visibleItemCount + (2 * overscanCount);
      const itemsToRender = [];

      for (let i = startIndex; i < endIndex; i++) {
        if (i >= 0 && i < itemCount) {
          itemsToRender.push(renderItem(i));
        }
      }

      setScrollPos(scrollTop);
      itemsRef.current = itemsToRender;
    };

    list.addEventListener('scroll', handleScroll);
    return () => list.removeEventListener('scroll', handleScroll);
  }, [itemCount, itemHeight]);

  return (
    <div className="virtual-list" ref={listRef} style={{ height: '300px', overflow: 'auto' }}>
      <div
        className="virtual-list-items"
        style={{
          transform: `translateY(-${Math.floor(scrollPos / itemHeight) * itemHeight}px)`,
          position: 'absolute',
          top: 0,
        }}
      >
        {itemsRef.current.map((item, index) => (
          <div key={index}>{item}</div>
        ))}
      </div>
    </div>
  );
};

这个虚拟列表组件可以根据实际需要进行调整和扩展,例如添加动态高度支持、更复杂的项渲染逻辑等。记住,虚拟列表的关键是在保持高性能的同时,只渲染可见的列表项或近可见区域的项。

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

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

相关文章

考研数学强化,880+660正确打开方式

1800题基础做完了&#xff1f;做的怎么样&#xff01; 之所以问你做的怎么样&#xff0c;是因为1800题做的好坏&#xff0c;直接决定了你要不要开始做880题和660题。 有的同学1800题做的很好&#xff0c;做完1800题之后开始做880660没毛病 但是有的同学就是纯纯的为了做题而…

Python 基础:文件

目录 一、从文件中读取数据1.1 读取整个文件1.2 逐行读取 二、写入文件2.1 写入空文件2.2 写入多行2.3 附加到文件 遇到看不明白的地方&#xff0c;欢迎在评论中留言呐&#xff0c;一起讨论&#xff0c;一起进步&#xff01; 本文参考&#xff1a;《Python编程&#xff1a;从入…

MySQL版本发布模型

MySQL 8.0 之后使用了新的版本控制和发布模型&#xff0c;分为两个主线&#xff1a;长期支持版&#xff08;LTS&#xff09;以及创新版。这两种版本都包含了缺陷修复和安全修复&#xff0c;都可以用于生产环境。 下图是 MySQL 的版本发布计划&#xff1a; 长期支持版 MySQL…

深度学习项目十六:根据训练好的权重文件推理图片--YOLO系列

文章目录 根据训练好的权重文件推理图片--YOLO系列一、自己构建YOLOv5推理代码1.1 对数据集进行模型训练1.2 对数据集进行模型推理检测1.3 自己编写推理函数1.3.1 针对单张进行推理1.3.2 针对文件夹下的图片进行推理二、自己构建YOLOv8推理代码2.1 对数据集进行模型训练2.2 对数…

HTML星空特效

目录 写在前面 完整代码 代码分析 运行效果 系列文章 写在后面 写在前面 100行代码实现HTML星空特效。 完整代码 全部代码如下。 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"&g…

R语言统计分析——图形的组合

参考资料&#xff1a;R语言实战【第2版】 在R种使用函数par()或layout()可以容易地组合多幅总括图形。 我们可以在par()函数中使用图形参数mfrowc(nrows,ncols)来创建按行填充的行数为nrows、列数为ncols的图形矩阵。另外&#xff0c;可以使用mfcolc(nrows,ncols)按列填充矩阵。…

SpringBoo+vue3+vite整合讯飞星火3.5通过webscoket实现聊天功能(前端代码)附带展示效果

访问地址&#xff1a; 天梦星服务平台 (tmxkj.top)https://tmxkj.top/#/site 后端文档&#xff1a; SpringBoovue3整合讯飞星火3.5通过webscoket实现聊天功能&#xff08;全网首发&#xff09;附带展示效果_springboot websocket vue3-CSDN博客https://blog.csdn.net/qq_53722…

GBT20041.21金属导管弯曲试验机

一、前言 电动金属导管弯曲试验机依据(GB/T20041.21-2008电缆管理用导管系统刚性导管系统的特殊要求》、《GB/T14823.1电气安装用导管特殊要求金属导管》、《JG/T3050建筑用绝缘电工套管及配件》及《ZBG33008聚氯乙稀塑料波纹电线管》开发的新型产品。适用于金属导管等材料做弯…

【话题】层出不穷的大模型产品,你怎么选?

大家好&#xff0c;我是全栈小5&#xff0c;欢迎阅读小5的系列文章&#xff0c;这是《话题》系列文章 目录 引言元宝体验产品介绍AI作画 文档总结AI超级产品文章推荐 引言 随着近日腾讯元宝APP的正式上线&#xff0c;国内大模型产品又添一员。 关于接连出现的“全能“大模型AI…

判断单链表是否带环且返回节点

今天鄙人为大家带来的是一道简单的逻辑运算题。用用到了一个我们在链表中提及过的方法快慢法。这道题其实没啥考的实际意义。只是我们如果能了解这道题的解决方法的话。对我们后面梳理逻辑会有很大的帮助。 单链表的题目 我们可以看到上面的题目。就是让我们判断是否带环。也许…

渲染农场深度解析:原理理解、配置要点与高效使用策略

许多设计领域的新手可能对“渲染农场”这一概念感到陌生。渲染农场是一种强大的计算资源集合&#xff0c;它通过高性能的CPU和GPU以及专业的渲染引擎&#xff0c;为设计项目提供必要的渲染支持。这种平台由多台计算机或渲染节点组成&#xff0c;形成一个分布式网络&#xff0c;…

统计信号处理基础 习题解答10-17

题目&#xff1a; 在选择不含信息的或者不假设任何先验知识的先验PDF时,我们需要从数据中得到最大的信息量。在这种方式下,数据是了解未知参数的主要贡献者。利用习题10.15的结果,这种方法可以通过选择使I最大的来实现。对于例10.1的高斯先验PDF,该如何选择和2使得 是不含信息…

N4中文分类

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊# 前言 前言 上周学习了英文文本分类&#xff0c;这次进行中文分类实战。 1. 数据读取 import pandas as pd train_data pd.read_csv(train.csv,sep\t,head…

qt.qpa.xcb: could not connect to display问题解决

1、问题描述 以服务器pi5作为远程解释器&#xff0c;本地win11使用vscode远程调试视觉时报错如下&#xff1a; qt.qpa.xcb: could not connect to display qt.qpa.plugin: Could not load the Qt platform plugin "xcb" in "xxxxx" even though it was …

室内灰尘对老人小孩危害不容忽视,资深家政推荐除灰尘空气净化器

正所谓“病从口入&#xff0c;尘从窗入”&#xff0c;室内灰尘问题不容小觑。尤其是对老人和小孩来说&#xff0c;灰尘中的有害物质更是威胁健康的重要因素。近期天气炎热&#xff0c;家家户户每天都会开窗通风&#xff0c;然而这也带来了灰尘和毛絮的问题。即使每天打扫&#…

java 线程之间通信-volatile 和 synchronized

你好&#xff0c;我是 shengjk1&#xff0c;多年大厂经验&#xff0c;努力构建 通俗易懂的、好玩的编程语言教程。 欢迎关注&#xff01;你会有如下收益&#xff1a; 了解大厂经验拥有和大厂相匹配的技术等 希望看什么&#xff0c;评论或者私信告诉我&#xff01; 文章目录 一…

LabVIEW Windows与RT系统的比较与选择

LabVIEW是一种系统设计和开发环境&#xff0c;广泛应用于各类工程和科学应用中。LabVIEW Windows和LabVIEW RT&#xff08;Real-Time&#xff09;是LabVIEW的两个主要版本&#xff0c;分别适用于不同的应用场景。以下从多个角度详细分析两者的区别&#xff0c;并提供选择建议。…

国际期货行情相关术语

1&#xff09;合约&#xff1a;期货行情表提供了期货交易的相关信息 &#xff0c;行情表中每一个期货合约都有合约代码&#xff08;由期货合约交易代码和合约到期月份组成&#xff09;来标识。 &#xff08;2&#xff09;开盘价&#xff1a;当日某一期货合约交易开始前五分钟集…

开发者配置项、开发者选项自定义

devOptions.vue源码 <!-- 开发者选项 &#xff08;CtrlAltShiftD&#xff09;--> <template><div :class"$options.name" v-if"visible"><el-dialog:custom-class"sg-el-dialog":append-to-body"true":close-on…

安装pytorch环境

安装&#xff1a;Anaconda3 通过命令行查显卡nvidia-smi 打开Anacanda prompt 新建 conda create -n pytorch python3.6 在Previous PyTorch Versions | PyTorch选择1.70&#xff0c;安装成功&#xff0c;但torch.cuda.is_available 返回false conda install pytorch1.7.0…