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

Android Chrome中requestAnimationFrame调用60次/秒但渲染仅30FPS问题咨询

为什么requestAnimationFrame调用次数和实际渲染次数不一致

requestAnimationFrame(以下简称rAF)的触发频率和实际屏幕上屏帧率是两个独立的统计维度,出现差异的核心原因有两个:

  • 安卓Chrome的动态功耗调节策略:绝大多数安卓设备默认开启自适应刷新率,系统和浏览器会根据当前显示内容的优先级动态调整屏幕刷新率,静态内容、低优先级动画会被限制在30FPS以降低功耗,只有视频、交互类动画等场景才会拉高到60FPS及以上。你提供的最小demo绘制内容固定不变,Chrome会判定为低优先级动画,自动压低渲染帧率。
  • 重复帧跳过机制:如果浏览器检测到前后两帧的视觉内容完全没有变化,会直接丢弃当前帧,不会提交到合成线程上屏,你当前的demo每帧都在同一位置绘制相同颜色的10x10方块,前后帧没有差异,大量重复帧被跳过,自然无法达到60FPS的上屏帧率。
  • 额外注意:如果设备开启了全局省电模式,会强制所有应用锁30FPS,也会出现这个问题。

如何实现60FPS正常渲染

按照以下优先级排查修改即可:

  • 先关闭设备的省电模式,在系统显示设置中把屏幕刷新率固定为60Hz,关闭自适应/智能刷新率选项,排除系统层面的帧率限制。
  • 保证每帧有明确的视觉变化,避免重复帧被丢弃。你的demo可以修改为清屏后绘制动态变化的内容,示例代码如下:
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext('2d');
ctx.fillStyle = 'red';
// 用偏移量让每帧绘制内容产生变化
let offsetX = 0;

var loop = function() {
  // 清空上一帧内容
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  // 更新绘制坐标
  offsetX = (offsetX + 2) % canvas.width;
  ctx.fillRect(offsetX, 0, 10, 10);
  
  requestAnimationFrame(loop);
}
loop();
  • 给Canvas元素添加will-change: transform CSS属性,主动提示浏览器该元素会持续产生动画,需要优先分配高刷新率资源,避免浏览器主动压低帧率。
  • 测试阶段移除不必要的console.log调用,频繁的日志输出会占用主线程资源,极端情况下也会影响合成线程调度,导致帧率下降。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 00:18:02