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表格虚拟滚动的原理和实现,包括如何计算可视区域、如何渲染数据、如何处理滚动事件等。通过虚拟滚动,我们可以轻松处理百万级的数据,实现流畅的滚动效果。

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

相关推荐
用户4099322502126 小时前
PostgreSQL UPDATE语句怎么玩?从改邮箱到批量更新的避坑技巧你都会吗?
后端·ai编程·trae
用户4099322502124 天前
PostgreSQL 17安装总翻车?Windows/macOS/Linux避坑指南帮你搞定?
后端·ai编程·trae
用户4099322502125 天前
能当关系型数据库还能玩对象特性,能拆复杂查询还能自动管库存,PostgreSQL 凭什么这么香?
后端·ai编程·trae
豆包MarsCode6 天前
基于 TRAE 的自动化测试用例智能生成方案
trae
岛风风6 天前
你还在让ai这样解决编程问题?
程序员·trae
用户4099322502126 天前
给接口加新字段又不搞崩老客户端?FastAPI的多版本API靠哪三招实现?
后端·ai编程·trae
程序员爱钓鱼7 天前
Go语言100个实战案例-项目实战篇:股票行情数据爬虫
后端·go·trae
用户4099322502128 天前
FastAPI秒杀库存总变负数?Redis分布式锁能帮你守住底线吗
后端·ai编程·trae
豆包MarsCode8 天前
AI 工具站开发:3 小时 SOLO,全栈开发+自动部署
trae
用户4099322502129 天前
FastAPI的CI流水线怎么自动测端点,还能让Allure报告美到犯规?
后端·ai编程·trae