核心是“该画时才画、该画多少就画多少”:用requestAnimationFrame主导节奏,配合isDirty标记、数据节流合并、LTTB降采样及离屏缓存,在30–60fps下实现低延迟、高清晰、低负载的实时渲染。

构建 Canvas 实时数据可视化渲染调度器,核心不是“拼命画”,而是“该画时才画、该画多少就画多少”。关键在于用 requestAnimationFrame 主导节奏,配合脏检查、节流合并和帧率控制,把 CPU 和 GPU 的负载稳在安全区间。
用 requestAnimationFrame 做主循环骨架
不用 setInterval,它不跟屏幕刷新同步,容易丢帧或堆积。requestAnimationFrame 天然对齐显示器垂直同步(VSync),每帧约 16.67ms(60fps)或 33.33ms(30fps)。
- 每次回调中只做两件事:检查是否需要更新、执行一次绘制
- 加时间戳判断,避免超频调用。例如目标 60fps,就跳过间隔不足 16ms 的帧
- 把数据更新(updateData)和绘图(draw)严格分离,确保计算不挤占渲染时间
引入 isDirty 标记控制重绘开关
数据变了,不代表每一帧都要重画整张图。用布尔标记代替盲目清屏,是省资源的第一步。
- 当新数据到达、缩放变化、窗口 resize 时,设 isDirty = true
- 渲染函数里只在 isDirty 为 true 时才 clearRect + draw,之后立即置 false
- 对局部动效(如某根柱子数值跳变),可细化到图元级 dirty 标记,进一步缩小重绘范围
高频数据要节流+批量处理
如果后端每 50ms 推一条数据,但屏幕最多 60fps,硬扛会白耗性能。必须做缓冲与聚合。
- 用数组暂存最近 3–5 帧数据,达到阈值或超时(如 100ms)再统一处理
- 对趋势类图表,用 LTTB 等算法降采样,保留视觉关键点,而非全量绘制
- 使用 TypedArray(如 Float32Array)存坐标数据,减少 GC 压力,也方便后续 Web Worker 协同
结合设备像素比与离屏缓存保清晰不掉帧
高清屏模糊、反复画网格线卡顿,往往是因为没做底层适配。
- 初始化时读取 window.devicePixelRatio,按比例放大 canvas.width/height,再用 CSS 缩回显示尺寸
- 把坐标轴、网格、标题等静态内容预先画进 offscreenCanvas,主循环只需 drawImage + 叠加动态层
- 给 getContext('2d') 加 { willReadFrequently: true } 提示(Chrome/Firefox 支持),优化像素读取性能


















