You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让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>

关键优化点说明

  1. 用requestAnimationFrame替代setInterval

    • requestAnimationFrame会和显示器的垂直同步(VSync)对齐,在240Hz显示器上会自动以240fps的频率触发,而setInterval无法做到这一点——它的执行时机独立于渲染流程,经常会和渲染帧冲突,导致丢帧或重复绘制,反而增加延迟。
    • 把帧率计算和绘制逻辑放在同一个循环里,确保两者完全同步,统计的FPS就是实际的渲染帧率。
  2. 优化输入事件处理

    • 避免在mousemove事件里每次创建新的mouse对象,直接更新已有对象的属性,减少内存分配和垃圾回收的开销。
    • 添加{ passive: true }选项,让浏览器提前知道这个事件监听器不会调用preventDefault(),可以优化事件处理的性能,进一步压缩输入到渲染的延迟。
  3. 匹配Canvas与显示分辨率

    • 如果Canvas尺寸和显示的实际像素不匹配,浏览器会自动进行缩放,增加额外的性能开销。通过设置c.width = window.innerWidth和c.height = window.innerHeight,可以让Canvas直接匹配屏幕分辨率,避免不必要的计算。

额外注意事项

  • 首先要确认你的显示器确实支持240Hz刷新率,并且在系统设置里已经开启该模式。
  • 部分浏览器的性能模式会限制帧率,比如Chrome的"性能"模式(设置>系统),需要关闭它才能达到最高帧率。
  • 复杂的绘制操作(比如大量矢量图形、滤镜效果)可能会成为性能瓶颈,需要尽量简化绘制逻辑,比如复用路径、减少不必要的状态切换。

内容的提问来源于stack exchange,提问作者Geoff Clements

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:42:32