Trae教你实现Canvas 表格,提高渲染性能

前言

你是否只会使用element、antd等组件库的表格?你是否只会谴责后端返回的数据很多,导致你的页面卡爆,卡成ppt,用户体验下降?你是否会因为数据量太大,导致页面卡顿,用户体验下降?虚拟列表,你是不是经常听到定高的列表,不定高的虚拟列表,这是不是听起来很懵逼,那么你是不是以为我会讲虚拟列表?

不,我今天不讲虚拟列表,今天我来讲canvas实现一个高性能的table,再也不担心后端返回大量数据,导致前端的页面卡顿,用户体验下降。

依旧是我们的Trae ai,先简单的提问,让Trae模拟大量的数据,这样就不用我们手动添加了,偷个懒吧,啊哈哈哈

看看最终的样式效果,滚动起来,一点都不卡顿,很丝滑

Trae的实现思路

一、Trae设计的思路

  • 目标:在普通浏览器环境中流畅渲染 10 万+ 行表格,滚动不卡顿。
  • 核心策略:Canvas 即时渲染 + 虚拟滚动。只绘制"可视区域内"的行,不创建海量 DOM 节点。
  • 关键优化:
    • 高 DPI 适配:一次性 setTransform(dpr, 0, 0, dpr, 0, 0) 消除模糊。
    • 预计算列几何:列累计偏移 colX[] 只算一次,循环直接查表。
    • requestAnimationFrame 合帧:滚动时只在下一帧绘制,避免重复触发。
    • 数据"按需生成":通过行号生成数据,不在内存里存放 10 万对象。

二、数据与内存策略

  • 不真正"持有"数据数组,而是利用行号 i 通过一个轻量的伪随机函数生成可复现的数据。这样总内存占用基本与总行数无关,只有可见行的文本参与绘制。
  • 优点:零初始化成本、零大对象分配、滚动时无需数据搬运。

Trae的实现代码

预计算列位置,避免重复相加成本

js 复制代码
  const colX = new Array(COLS.length + 1);
  function computeColX() {
    colX[0] = 0;
    for (let i = 0; i < COLS.length; i++) colX[i + 1] = colX[i] + COLS[i];
  }
  computeColX();

用行号 i 生成稳定的"随机"数据,避免存储大数组

js 复制代码
function rand(i){ const x = Math.sin(i * 9999) * 10000; return x - Math.floor(x); }
function rowData(i){
  const n = i + 1;
  const age = 18 + Math.floor(rand(n)*40);
  const score = (rand(n*3)*100).toFixed(2);
  const level = ['Bronze','Silver','Gold','Platinum','Diamond'][Math.floor(rand(n*7)*5)];
  const status = rand(n*11) > 0.5 ? '正常' : '冻结';
  const city = ['上海','北京','深圳','杭州','成都','武汉','西安','广州'][Math.floor(rand(n*5)*8)];
  const time = new Date(1600000000000 + Math.floor(rand(n*13)*1e10)).toISOString().slice(0,19).replace('T',' ');
  return [n, '用户'+n, city, age, score, level, status, time, 'OD'+(100000+n), '---'];
}

关键的虚拟滚动实现

js 复制代码
const firstRow = Math.max(0, Math.floor((viewTop - HEADER_H) / ROW_H));
const visibleCount = Math.ceil(h / ROW_H) + 1;
const lastRow = Math.min(TOTAL_ROWS, firstRow + visibleCount);
let y = HEADER_H - ((viewTop - HEADER_H) % ROW_H);

高 DPI 渲染适配

js 复制代码
const dpr = Math.max(1, Math.floor(window.devicePixelRatio || 1));
canvas.width = w * dpr; canvas.height = h * dpr;
ctx.setTransform(dpr, 0, 0, dpr, 0, 0); // 只设置一次

总结

虚拟滚动是一种优化长列表渲染的技术,通过只渲染可视区域内的元素,大幅减少 DOM 操作和重绘,提高性能。

本文介绍了canvas表格虚拟滚动的原理和实现,包括如何计算可视区域、如何渲染数据、如何处理滚动事件等。通过虚拟滚动,我们可以轻松处理百万级的数据,实现流畅的滚动效果。

如果你之前没有接触过虚拟滚动,希望本文能帮你入门。如果你已经熟悉虚拟滚动,希望本文能帮你优化你的实现。

相关推荐
飞哥数智坊16 小时前
TRAE 支持自定义模型了,配置个 DeepSeek V4 试试
deepseek·trae
陈蒙_2 天前
三板斧解决 Trae 卡顿
安卓·agent·ai编程·trae·trae 卡顿
豆包MarsCode2 天前
TRAE × IGA Pages:TRAE 中国版如何快速实现一键部署
trae
豆包MarsCode3 天前
万字干货|AI 时代的 Git 版本管理,你用对了吗?
trae
茶茶敲代码4 天前
Simpack的DOE处理
python·pygame·trae·simpack
豆包MarsCode4 天前
SOLO 桌面端+网页端语音输入功能上线,TRAE × 影石 Insta360 限定 Mic Air 正式发布!
trae
深念Y5 天前
TraeCN 新老用户排队机制差异的实测与分析
ide·编程·claude·模型·cli·trae·vibe coding
搬砖的前端8 天前
AI编辑器开源主模型搭配本地模型辅助对标GPT5.2/GPT5.4/Claude4.6(前端开发专属)
人工智能·开源·claude·mcp·trae·qwen3.6·ops4.6
FEF前端团队9 天前
Skill 入门指南:从零开始打造你的智能编程助手
aigc·ai编程·trae
豆包MarsCode9 天前
从创意到落地,SOLO 如何让短剧制作更高效
trae