前端虚拟列表实现:别再渲染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

AI绘画提示词生成器:从原理到实战的开发者指南

快速体验 在开始今天关于 AI绘画提示词生成器:从原理到实战的开发者指南 的探讨之前,我想先分享一个最近让我觉得很有意思的全栈技术挑战。 我们常说 AI 是未来,但作为开发者,如何将大模型(LLM)真正落地为一个低延迟、可交互的实时系统,而不仅仅是调个 API? 这里有一个非常硬核的动手实验:基于火山引擎豆包大模型,从零搭建一个实时语音通话应用。它不是简单的问答,而是需要你亲手打通 ASR(语音识别)→ LLM(大脑思考)→ TTS(语音合成)的完整 WebSocket 链路。对于想要掌握 AI 原生应用架构的同学来说,这是个绝佳的练手项目。 从0到1构建生产级别应用,脱离Demo,点击打开 从0打造个人豆包实时通话AI动手实验 AI绘画提示词生成器:从原理到实战的开发者指南 背景与痛点 AI绘画的兴起让提示词(Prompt)成为连接创意与生成结果的关键纽带。然而在实际开发中,构建一个高效的提示词生成器常面临以下挑战: * 质量不稳定:生成的提示词可能过于笼统(如"

llama.cpp最新版Windows编译全记录:从源码下载到模型测试(含w64devkit配置)

llama.cpp Windows编译实战:从工具链配置到模型部署全解析 在本地运行大型语言模型正成为开发者探索AI能力的新趋势,而llama.cpp以其高效的C++实现和跨平台特性脱颖而出。本文将深入探讨Windows平台下llama.cpp的完整编译流程,特别针对开发者常遇到的环境配置、API兼容性和性能优化问题进行系统化梳理。 1. 开发环境准备与工具链配置 Windows平台编译C++项目需要精心配置工具链,而w64devkit提供了一个轻量级但功能完整的解决方案。与常见的Visual Studio或MinGW-w64不同,w64devkit将所有必要工具集成在单个便携包中,特别适合需要干净编译环境的开发者。 核心组件获取步骤: 1. 访问w64devkit官方GitHub仓库,下载最新稳定版本(当前推荐1.23.0) 2. 解压至不含中文和空格的路径,例如D:\dev\w64devkit-1.23.0 3. 验证基础功能:运行w64devkit.exe后执行gcc --version 注意:Windows 7用户需确保系统已安装KB2533623补丁,否则

春晚机器人刷屏背后:AI大模型风口已来,建议收藏!普通人也能上车的高薪赛道

春晚机器人刷屏背后:AI大模型风口已来,建议收藏!普通人也能上车的高薪赛道

春晚落幕之后,全网都在热议同一个话题:这届晚会的机器人含量也太高了! 不管是主舞台上灵活走位、完成高难度动作的人形机器人,还是在幕后支撑节目创意、视觉效果的AI大模型,整台晚会从头到尾都被满满的科技感包围。 很多人看完只觉得新鲜、震撼,却没看懂其中真正的信号: 春晚机器人刷屏,从来不是一场单纯的技术表演,而是一个非常直白的行业信号——AI和机器人已经彻底走出实验室,真正走进普通人的生活,还悄悄带火了两个藏在幕后的黄金赛道。 最先被引爆的,就是机器人租赁这个小众又暴利的生意。 春晚热度一上来,线下机器人需求直接爆发。 机器人租赁服务平台擎天租公布了一组非常直观的数据:今年春节期间,平台订单环比增长近70%。 图片来源网络,侵删 可能很多人会好奇:过年租机器人,到底能用来干嘛? 其实应用场景比你想象中更接地气。 商场需要迎宾机器人引流揽客,景区需要讲解机器人服务游客,商圈活动、企业年会需要互动机器人带动气氛,就连很多门店引流、社区活动,都愿意租一台机器人撑场面、吸眼球。 以前过年,大家拼的是年味、是团聚;现在年轻人更追求新潮体验,机器人不用高价购买,按天租赁就能用,

LLaMA - Factory安装部署及微调流程

LLaMA - Factory安装部署及微调流程

LLaMA - Factory安装部署及微调流程笔记 一、部署前准备 (一)明确依赖环境 1. 必备依赖 * Python建议采用3.11版本,该版本在大模型系列中适配性佳,能更好地支持LLaMA - Factory的运行。 * CUDA可选择12.1或12.2版本。实际使用中,即便下载时Pytorch最高仅对应12.1(显卡最高支持12.2) ,也可正常安装使用。此外,torch、transformers、datasets、accelerate、peft、trl等库也必不可少,各有其最低和推荐版本,安装时务必严格遵循版本要求,否则易出现难以解决的未知问题。 2. 可选依赖 3. deepspeed、bitsandbytes、vllm、flash - attn等属于可选依赖。 例如deepspeed可减少内存消耗,适用于内存资源有限的情况,但可能会使训练时间拉长。即便不安装这些可选依赖,LLaMA - Factory依然能够完成微调任务。