前端虚拟列表实现:别再渲染10000个DOM节点了

前端虚拟列表实现:别再渲染10000个DOM节点了

前端虚拟列表实现:别再渲染10000个DOM节点了

毒舌时刻

这代码写得跟网红滤镜似的——仅供参考。

各位前端同行,咱们今天聊聊前端虚拟列表。别告诉我你还在一次性渲染10000个列表项,那感觉就像把10000本书全部摆在桌面上——既占地方又难找。

为什么你需要虚拟列表

最近看到一个项目,一个下拉列表有5000个选项,全部渲染导致页面卡死,我差点当场去世。我就想问:你是在做列表还是在做性能杀手?

反面教材

// 反面教材:一次性渲染所有数据 function BigList({ items }) { return ( <ul style={{ height: '400px', overflow: 'auto' }}> {items.map(item => ( <li key={item.id} style={{ height: '50px' }}> {item.name} </li> ))} </ul> ); } // 使用 <BigList items={Array.from({ length: 10000 }, (_, i) => ({ id: i, name: `Item ${i}` }))} /> // 浏览器:我太难了 

毒舌点评:这代码,我看了都替浏览器着急。渲染10000个DOM节点,你是想让用户的电脑变成暖炉吗?

前端虚拟列表的正确姿势

1. 基础虚拟列表实现

// 正确姿势:基础虚拟列表 import { useState, useRef, useMemo, useCallback } from 'react'; function VirtualList({ items, itemHeight, containerHeight }) { const [scrollTop, setScrollTop] = useState(0); const containerRef = useRef(null); // 计算可见区域 const visibleCount = Math.ceil(containerHeight / itemHeight); const totalHeight = items.length * itemHeight; // 计算起始和结束索引 const startIndex = Math.floor(scrollTop / itemHeight); const endIndex = Math.min(startIndex + visibleCount + 1, items.length); // 获取可见项 const visibleItems = useMemo(() => { return items.slice(startIndex, endIndex); }, [items, startIndex, endIndex]); // 偏移量 const offsetY = startIndex * itemHeight; const handleScroll = useCallback((e) => { setScrollTop(e.target.scrollTop); }, []); return ( <div ref={containerRef} style={{ height: containerHeight, overflow: 'auto' }} onScroll={handleScroll} > <div style={{ height: totalHeight, position: 'relative' }}> <div style={{ transform: `translateY(${offsetY}px)` }}> {visibleItems.map((item, index) => ( <div key={item.id} style={{ height: itemHeight }} className="virtual-list-item" > {item.name} </div> ))} </div> </div> </div> ); } // 使用 function App() { const items = Array.from({ length: 10000 }, (_, i) => ({ id: i, name: `Item ${i}` })); return ( <VirtualList items={items} itemHeight={50} containerHeight={400} /> ); } 

2. 使用react-window

// 正确姿势:使用react-window import { FixedSizeList as List } from 'react-window'; function VirtualList({ items }) { const Row = ({ index, style }) => ( <div style={style} className="list-item"> {items[index].name} </div> ); return ( <List height={400} itemCount={items.length} itemSize={50} > {Row} </List> ); } // 使用 function App() { const items = Array.from({ length: 10000 }, (_, i) => ({ id: i, name: `Item ${i}` })); return <VirtualList items={items} />; } 

3. 使用vue-virtual-scroller

<!-- Vue3中使用vue-virtual-scroller --> <template> <RecycleScroller :items="items" :item-size="50" key-field="id" v-slot="{ item }" > <div> {{ item.name }} </div> </RecycleScroller> </template> <script setup> import { RecycleScroller } from 'vue-virtual-scroller'; import 'vue-virtual-scroller/dist/vue-virtual-scroller.css'; const items = Array.from({ length: 10000 }, (_, i) => ({ id: i, name: `Item ${i}` })); </script> <style> .scroller { height: 400px; } .item { height: 50px; display: flex; align-items: center; padding: 0 20px; } </style> 

毒舌点评:早这么写,你的列表早流畅了。别告诉我你还在渲染10000个DOM节点,那你还是趁早去用分页吧。

实战技巧:虚拟列表指南

1. 虚拟列表原理

  1. 只渲染可见项:只渲染视口内的元素
  2. 计算偏移量:通过transform移动内容
  3. 动态高度支持:预估高度或动态计算

2. 最佳实践

  1. 固定高度:优先使用固定高度,性能好
  2. 缓冲区域:上下多渲染几个item,避免白屏
  3. 滚动优化:使用requestAnimationFrame

最后想说的

虚拟列表不是炫技,是性能优化。别再渲染10000个DOM节点了——虚拟化一下,你的应用会飞起来。

虚拟列表就像图书馆的检索系统,不需要把所有书都摆在桌上,只需要展示你想看的那几本。别做图书搬运工,做图书管理员。

Read more

2026新手小白AI创业变现指南(二)- AI写作辅助平台

2026新手小白AI创业变现指南(二)- AI写作辅助平台

刚刚更新了2026新手小白AI创业变现指南l列表,新增加了测试过的炼字工坊、蛙蛙写作、笔杆平台(学术论文平台,非通用写作平台)。想简单介绍下,详情请点击2026新手小白AI创业变现指南(一)中平台列表中平台名称看详细介绍。 一、炼字工坊 平台基础信息 项目内容平台名称炼字工坊官方网址https://lianzigongfang.com平台介绍专为网文/剧本/漫剧作者设计的AI创作平台,帮你把精力花在“故事和表达”上,把重复、耗时、卡壳的部分交给AI。相比通用AI,炼字工坊在长篇稳定性上有明显优势。它用「问答+抽卡」帮你定题材卖点,用「设定库」自动归档世界观和角色,用「分层大纲」把控剧情节奏,用「续写润色」解决卡文问题。最重要的是:你的作品不会用于AI训练,版权完全归你。核心定位长篇创作的全流程辅助,从灵感、设定到续写、润色,让你专注创作本身。 🎯 它和通用AI(如DeepSeek、千问)

如何突破字幕处理效率瓶颈?Whisper技术驱动的全流程解决方案

如何突破字幕处理效率瓶颈?Whisper技术驱动的全流程解决方案 【免费下载链接】video-subtitle-master批量为视频生成字幕,并可将字幕翻译成其它语言。这是一个客户端工具, 跨平台支持 mac 和 windows 系统 项目地址: https://gitcode.com/gh_mirrors/vi/video-subtitle-master 在全球化内容传播的今天,视频字幕处理已成为内容创作与分发的关键环节。传统字幕制作流程面临三大核心痛点:单任务处理耗时过长、多语言翻译质量参差不齐、硬件资源利用率低下。基于OpenAI Whisper语音识别技术的视频字幕批量处理工具,通过整合自动化语音转写与多引擎翻译能力,为突破这些效率瓶颈提供了全新可能。本文将从技术原理、实际应用与价值分析三个维度,深入剖析这款工具如何重构字幕处理工作流,并横向对比现有解决方案的优劣势。 诊断字幕处理行业痛点 效率瓶颈的底层成因 当前字幕制作主要依赖人工听写或单一引擎处理,导致三个维度的效率损耗:时间维度上,单小时视频需3-5小时人工转录;质量维度上,专业术语翻译准确率不足75%;资

AI 编程工具选型:Copilot、Cursor、Codex 核心差异

AI 编程工具选型:Copilot、Cursor、Codex 核心差异

【如文章引起大家共鸣,请“点赞”以及“转发”,以支持继续创作,谢谢大家!】 朋友们大家好!今天咱们不聊那些虚头巴脑的,直接来点实在的——AI编程工具选型,Copilot、Cursor、Codex这仨到底咋选?别急,我这就用最接地气的方式,给你唠唠它们的“脾气秉性”,保证你听完就能上手挑! 先说Copilot,这哥们儿可是“代码补全界的扛把子”!它就像你身边的“代码小秘书”,你敲代码时,它就在旁边默默观察,你刚敲个“for”,它立马给你补上“(int i=0;i<n;i++)”,那叫一个快!而且,它还支持多IDE,VS Code、JetBrains啥的,都能无缝对接。不过呢,Copilot也有个“小毛病”,就是它更擅长“补全”,对于复杂的代码重构或者项目级理解,就有点力不从心了。

GitHub Awesome Copilot 项目深度解析:社区驱动的 AI 编程助手增强工具库

GitHub Awesome Copilot 项目深度解析:社区驱动的 AI 编程助手增强工具库

概要 GitHub Awesome Copilot 是一个由社区驱动的开源项目,专注于为 GitHub Copilot 提供丰富的自定义增强工具。该项目汇集了全球开发者贡献的指令、提示词、配置和代理,旨在帮助用户最大化利用 GitHub Copilot 的 AI 编程能力。通过提供模块化的自定义组件,该项目将 Copilot 从一个通用的代码生成工具,升级为能够适应特定领域、工作流和最佳实践的智能编程伙伴。随着 AI 编程助手技术的快速发展,此类社区项目在推动工具实用性和普及性方面扮演着关键角色,特别是在个性化、专业化场景的支持上。 整体架构流程 Awesome GitHub Copilot 项目采用模块化、分层式的架构设计,确保各类自定义组件能够独立管理又相互协作。整体架构流程可分为五个核心层次: 1. 资源层(Resource Layer):作为基础层,包含所有原始的自定义组件文件,如提示词文件(.prompt.md)、指令文件(.instructions.md)