Canvas绘制网格的高性能方案是缓存复用+整数坐标对齐+合并绘制:初始化时将固定网格预绘至离屏Canvas,每帧仅drawImage贴图;确保坐标宽高为整数并关闭抗锯齿;水平/竖直线分别合并为长矩形绘制,大幅减少fillRect调用次数。

多次调用 fillRect 绘制网格背景本身不是高性能方案,但通过合理优化(如批量绘制、避免重复计算、利用 canvas 缓存),它完全可以做到流畅渲染,尤其适用于动态网格或需频繁更新的场景。
复用 canvas 缓存,避免每帧重绘
如果网格线间距、颜色、大小固定,最有效的做法是:只在初始化或参数变更时,用一次循环把整个网格画到一个离屏 canvas 上,之后每帧直接用 drawImage 贴图。这样完全规避了反复调用 fillRect 的开销。
- 创建一个与目标区域等大的离屏 canvas:
const offscreen = document.createElement('canvas'); - 设置其宽高,并获取 2D 上下文
- 用双层循环(x 方向线 + y 方向线)调用
fillRect绘制所有格线(注意:画线推荐用strokeRect或lineTo更精准;若坚持用fillRect模拟线,宽度设为 1 像素,确保整数坐标对齐像素边界) - 后续渲染只需:
ctx.drawImage(offscreen, 0, 0);
整数坐标对齐 + 关闭抗锯齿
浏览器对非整数坐标的 fillRect 会触发子像素渲染和抗锯齿,显著拖慢性能。网格绘制必须保证所有坐标、宽高都是整数,且开启像素对齐优化:
- 用
Math.round()或位运算(如x | 0)确保 x/y/width/height 全为整数 - 设置
ctx.imageSmoothingEnabled = false;(虽主要影响 drawImage,但部分浏览器也关联 fillRect 渲染路径) - 避免缩放 canvas 或用 CSS 改变 canvas 显示尺寸——这会导致隐式重采样
合并相邻矩形,减少 fillRect 调用次数
默认逐条画线(如 1px 宽竖线)会触发数百次 fillRect。可将多条平行线合并为一个长矩形:
将 Markdown 文章转换为微信公众号兼容的纯 HTML 格式。当用户要求"转成微信格式"、"生成公众号文章 HTML"、"排版到微信草稿箱"、"微信粘贴格式"时触发。输出带内联样式的纯 HTML,微信编辑器可直接渲染,无需额外适配。支持标题、段落、列表、粗体、行内代码、表格、引用块、代码块、配图的完整转换。
立即学习“前端免费学习笔记(深入)”;
- 水平线:绘制高度为 1、宽度为 canvas 宽度的矩形,y 坐标为
i * spacing - 竖直线:绘制宽度为 1、高度为 canvas 高度的矩形,x 坐标为
i * spacing - 这样 N×N 网格只需约
2 × (canvasWidth / spacing + canvasHeight / spacing)次调用,而非O(N²)
使用 requestAnimationFrame 控制绘制节奏
即使做了缓存,若在鼠标移动等高频事件中无节制重绘,仍可能卡顿。应:
- 仅在网格参数(如缩放、偏移、间距)真正变化时才重建缓存 canvas
- 动画类交互(如平滑拖拽网格)用
requestAnimationFrame统一驱动,避免同步阻塞 - 必要时加节流(throttle),例如 60fps 下最多每 16ms 更新一次
不复杂但容易忽略:高性能网格不在于“怎么多调用 fillRect”,而在于“怎么少调用、怎么不重复调用”。缓存 + 整数坐标 + 合并绘制,三者配合,万格背景也能稳 60fps。


















