DATA TABLE
虚拟滚动Virtual Scroll
只渲染可视区内的行,滚动时复用 DOM。把万级列表的渲染成本从「行数」降到「可视行数」。
效果预览
1用户登录成功info
2API 响应 200 OKinfo
3支付回调超时warn
4库存同步完成info
5写入失败 · 重试中error
适合用在哪
超过 500-1000 行的列表/表格;日志、消息记录、大数据量后台。
容易踩的坑
- 浏览器 Ctrl+F 只能搜到已渲染的二三十行,用户以为数据不存在,需提供站内搜索。
- overscan 设为 0,快速滚动时出现白屏闪烁,一般保留 5-10 行缓冲。
- 行高不固定还按固定值计算,滚动条位置漂移,跳到底部时内容错位。
设计提示词 · Prompt
虚拟滚动(Virtual Scroll):核心是只渲染视口内的行 —— 用一个固定高度的滚动容器(overflow:auto),监听 scroll 计算 startIndex = floor(scrollTop / rowHeight),只渲染 [startIndex, startIndex + 可视行数 + overscan] 这一段,外层用一个 height = 总行数 × rowHeight 的占位元素撑出正确滚动条。实现可用 @tanstack/react-virtual、react-window,或手写。要点:行高必须固定(变高会显著复杂化);滚动条位置要能反映真实进度(可用一个指示条);无障碍上给容器 role="grid" 与 aria-rowcount/aria-rowindex,否则屏幕阅读器只看到局部。
Virtual Scroll: the core idea is rendering only rows inside the viewport — use a fixed-height scroll container (overflow:auto), listen to scroll and compute startIndex = floor(scrollTop / rowHeight), render only the slice [startIndex, startIndex + visible row count + overscan], and use an outer spacer element with height = total rows × rowHeight to produce a correct scrollbar. Implement with @tanstack/react-virtual, react-window, or by hand. Key points: row height must be fixed (variable heights add significant complexity); the scrollbar position must reflect real progress (an indicator bar can help); for accessibility, give the container role="grid" with aria-rowcount/aria-rowindex, otherwise screen readers only see a fragment.
常见搭配
同一页面里经常和「虚拟滚动」一起出现的模式,可以收藏后用「组合收藏为整页提示词」一起交给 AI。
演示 HTML 结构
<div class="s d-center">
<div class="tb-virt">
<div class="tb-virt__r"><em>1</em><span class="tb__c" style="flex:1">用户登录成功</span><span class="tb__badge tb__badge--g">info</span></div>
<div class="tb-virt__r"><em>2</em><span class="tb__c" style="flex:1">API 响应 200 OK</span><span class="tb__badge tb__badge--g">info</span></div>
<div class="tb-virt__r"><em>3</em><span class="tb__c" style="flex:1">支付回调超时</span><span class="tb__badge tb__badge--y">warn</span></div>
<div class="tb-virt__r"><em>4</em><span class="tb__c" style="flex:1">库存同步完成</span><span class="tb__badge tb__badge--g">info</span></div>
<div class="tb-virt__r"><em>5</em><span class="tb__c" style="flex:1">写入失败 · 重试中</span><span class="tb__badge" style="background:#fee2e2;color:#b91c1c">error</span></div>
<div class="tb-virt__scroll"></div>
<div class="tb-virt__fade"></div>
</div>
</div>