requestanimationframe 在页面不可见时自动暂停回调,前提是不主动干扰该机制;需满足页面隐藏、无强制调用、无定时器驱动、渲染上下文正常释放等条件,并配合 visibilitychange 事件清理资源。

页面不可见时,requestAnimationFrame 会自动暂停回调,这是浏览器内置行为,无需手动干预——但前提是你的动画逻辑本身不主动干扰这个机制。
确保自动暂停生效的关键点
浏览器只在满足以下条件时才真正暂停 rAF:
- 页面处于其他标签页、最小化窗口、或系统级休眠状态
- 你的代码没有在不可见期间强行调用
requestAnimationFrame(比如在定时器里兜底触发) - 没有使用
setTimeout/setInterval驱动主循环,否则它们仍可能唤醒主线程 - Canvas 或 WebGL 渲染上下文未被异常持有(如未释放的纹理、未停止的音频分析器)
配合 visibilitychange 事件做显式控制
虽然 rAF 自动暂停,但结合 visibilitychange 可以更稳妥地清理资源:
- 监听
document.addEventListener('visibilitychange', ...) - 当
document.hidden === true时,调用cancelAnimationFrame(id)并暂停逻辑更新(如物理模拟、音频采样) - 恢复可见时,重置时间戳并重新发起
requestAnimationFrame - 注意:不要仅靠
cancelAnimationFrame来“暂停”,它只是取消当前帧请求;重点是停止递归调用链条
避免常见干扰行为
这些做法会让 rAF 暂停失效或间接耗电:
- 在 rAF 回调中反复创建/销毁 Canvas 2D 上下文或 ImageBitmap
- 持续轮询
performance.now()或Date.now()而不做可见性判断 - 使用
canvas.toDataURL()或频繁读取像素(getImageData),触发强制同步渲染 - 开启硬件加速但 GPU 缓存异常(表现为 Chrome 后台 GPU 占用飙升),此时需关闭硬件加速或清空 GPU 缓存
移动端特别提醒
在 iOS Safari 和部分安卓 WebView 中,visibilitychange 触发可能有延迟或遗漏:
- 可补充监听
pagehide/pageshow事件作为后备 - 对长时间运行的 Canvas 动画,建议在
hidden状态下主动释放OffscreenCanvas或暂停WebGLRenderingContext - 避免在不可见时仍播放音频或维持 WebRTC 连接,这些会阻止浏览器进入深度节电模式
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











