Canvas卡顿主因是每帧全屏clearRect、频繁切换fillStyle和逐个fillText;应改用局部清除、批量绘制、样式复用及离屏缓存优化。

Canvas 性能卡在 15–30 FPS?不是数据量太大,而是每帧都在重复干三件事:clearRect(0, 0, w, h)、频繁切换 ctx.fillStyle、逐个调用 fillText。这些操作单次看着没事,100 次就吃掉 30ms,直接超帧预算。
为什么 clearRect 全屏清空是性能杀手
全屏清空看似“稳妥”,实则把所有静态内容(网格线、坐标轴、图例)都擦掉重画。而它们根本没变——80% 的绘制工作纯属浪费。
- 只清除变化区域:
clearRect(x, y, width, height)替代全屏清空,尤其适合局部更新的曲线、热力格子 - 若动态区域分散,改用“脏矩形合并”:收集所有变动坐标,用
getBoundingClientRect()合并为最小包围矩形再清 - 避免在
requestAnimationFrame循环里无条件调用clearRect;先判断是否真有更新,再清
ctx.fillStyle 和 ctx.font 切换为何拖慢渲染
每次设 ctx.fillStyle = '#2a5f8c' 或 ctx.font = '14px sans-serif' 都会触发 GPU 状态切换,开销约 0.3ms/次。100 次就是 30ms —— 超过两帧时长。
- 批量绘制同色元素:统一设一次
ctx.fillStyle,再一口气画完所有矩形/圆点 - 文字复用样式:提前设好
ctx.font、ctx.textAlign、ctx.textBaseline,避免每行重设 - 固定标签(如“内存使用率:”)直接缓存为离屏
canvas,运行时drawImage复用,跳过文本渲染
高 DPI 屏上 Canvas 与 DOM 错位怎么修
错位不是 Canvas 画歪了,是 canvas.width/canvas.height 没乘 window.devicePixelRatio。CSS 显示 1920px 宽,但 canvas 物理像素只有 1920,坐标系被压缩,DOM 按 CSS 像素定位,自然偏移。
把任意文章或文档内容转换成精美的全屏翻页 HTML 演示文件(幻灯片风格)。当用户发来一篇文章、文档链接、Markdown 内容、或粘贴的文本,并且希望生成演示用的 HTML 时触发。支持任意内容来源:iWiki 链接、KM 链接、本地文件路径、直接粘贴的文本。生成的 HTML 文件保存到本地工作区,并通过企微直接发送给用户。触发词示例:帮我把这篇文章做成PPT、转成演示文档、生成HTML幻灯片、做个演示、转成可以演示的格式、article to deck、make a slide。
立即学习“前端免费学习笔记(深入)”;
- 初始化必须同步:
canvas.width = canvas.clientWidth * window.devicePixelRatio,canvas.height = canvas.clientHeight * window.devicePixelRatio - 紧接着调用
ctx.scale(dpr, dpr),之后所有绘图坐标仍写 CSS 像素值(如fillRect(10, 10, 20, 20)),无需手动换算 - 叠加的 DOM 元素(tooltip、弹窗)加
transform: translateZ(0)或will-change: transform,防被 Canvas 合成层遮挡
Canvas 拦截鼠标事件导致底层 SVG/DOM 失效
Canvas 默认吃掉所有 pointer 事件,哪怕放在 SVG 下面,鼠标也点不到底层节点——这是浏览器默认行为,不是 bug。
- 绝大多数场景下,给 Canvas 加
style="pointer-events: none",让事件自然穿透 - 需要 Canvas 响应交互时(如拖拽热力图),临时切回
pointer-events: auto,再用canvas.getBoundingClientRect()+event.clientX/Y手动映射坐标 - 确保 SVG 内部节点显式声明
pointer-events="visiblePainted",否则fill="none"的路径或空<text></text>标签无法触发事件
真正卡顿的根源往往藏在“看起来没问题”的惯性写法里:全屏清空、样式乱切、DPR 不适配、事件不穿透。这些点单独看都不起眼,但叠加起来就能把 60 FPS 拉到 15。优化不是堆技巧,而是识别哪些操作本就不该每帧发生。


















