如何让Canvas渲染帧率突破60fps?目标240+fps降低输入延迟
如何实现240+fps的Canvas渲染以降低输入延迟
首先,你遇到的setInterval(draw, 0)无法突破60fps的问题,核心原因有两个:
- 浏览器对
setInterval有最小延迟限制(通常是4ms),而且它的执行时机和浏览器的渲染管道完全不同步,就算你设0,也会被浏览器节流,最多只能和屏幕默认刷新率(多数为60Hz)对齐。 - 你的代码里把FPS计算和绘制逻辑拆成了两个独立循环,不仅效率低,还会导致绘制和帧率统计不同步,进一步限制了实际能达到的帧率。
要实现240+fps的渲染(前提是你的显示器支持240Hz刷新率),我们需要用requestAnimationFrame来驱动整个渲染流程——它是浏览器专门为动画设计的API,会和显示器的刷新周期同步,在支持高刷新率的设备上自动以更高频率触发(比如240Hz下每~4.16ms触发一次),同时避免不必要的重绘,从根本上降低输入延迟。
修改后的完整代码
<canvas id="myCanvas"></canvas> <script> var c = document.getElementById("myCanvas"); // 确保Canvas尺寸匹配显示分辨率,避免缩放开销 c.width = window.innerWidth; c.height = window.innerHeight; var ctx = c.getContext("2d"); // 初始化鼠标位置,避免重复创建对象 var mouse = {x: 0, y: 0}; const times = []; let fps; // 合并帧率计算与绘制逻辑到同一个渲染循环 function renderLoop() { // 计算当前FPS const now = performance.now(); while (times.length > 0 && times[0] <= now - 1000) { times.shift(); } times.push(now); fps = times.length; // 绘制逻辑 ctx.fillStyle = "black"; ctx.fillRect(0, 0, c.width, c.height); ctx.strokeStyle = "white"; ctx.beginPath(); ctx.arc(mouse.x, mouse.y, 40, 0, 2 * Math.PI); ctx.stroke(); ctx.font = "30px Comic Sans MS"; ctx.fillStyle = "red"; ctx.textAlign = "center"; ctx.fillText(fps, c.width / 2, c.height / 2); // 调度下一帧,保持渲染同步 window.requestAnimationFrame(renderLoop); } // 启动渲染循环 renderLoop(); // 优化鼠标事件处理:直接更新已有对象的属性,减少内存开销 document.addEventListener('mousemove', function(event){ mouse.x = event.clientX; mouse.y = event.clientY; }, { passive: true }); // passive: true 告诉浏览器不会阻止默认行为,提升事件处理效率 </script>
关键优化点说明
用requestAnimationFrame替代setInterval
requestAnimationFrame会和显示器的垂直同步(VSync)对齐,在240Hz显示器上会自动以240fps的频率触发,而setInterval无法做到这一点——它的执行时机独立于渲染流程,经常会和渲染帧冲突,导致丢帧或重复绘制,反而增加延迟。- 把帧率计算和绘制逻辑放在同一个循环里,确保两者完全同步,统计的FPS就是实际的渲染帧率。
优化输入事件处理
- 避免在
mousemove事件里每次创建新的mouse对象,直接更新已有对象的属性,减少内存分配和垃圾回收的开销。 - 添加
{ passive: true }选项,让浏览器提前知道这个事件监听器不会调用preventDefault(),可以优化事件处理的性能,进一步压缩输入到渲染的延迟。
- 避免在
匹配Canvas与显示分辨率
- 如果Canvas尺寸和显示的实际像素不匹配,浏览器会自动进行缩放,增加额外的性能开销。通过设置
c.width = window.innerWidth和c.height = window.innerHeight,可以让Canvas直接匹配屏幕分辨率,避免不必要的计算。
- 如果Canvas尺寸和显示的实际像素不匹配,浏览器会自动进行缩放,增加额外的性能开销。通过设置
额外注意事项
- 首先要确认你的显示器确实支持240Hz刷新率,并且在系统设置里已经开启该模式。
- 部分浏览器的性能模式会限制帧率,比如Chrome的"性能"模式(设置>系统),需要关闭它才能达到最高帧率。
- 复杂的绘制操作(比如大量矢量图形、滤镜效果)可能会成为性能瓶颈,需要尽量简化绘制逻辑,比如复用路径、减少不必要的状态切换。
内容的提问来源于stack exchange,提问作者Geoff Clements
相关产品推荐
相关产品推荐

