何时调用requestAnimationFrame()?是否需用其包裹所有视图视觉变更操作?
requestAnimationFrame()里? 这是个相当务实的问题——答案不是绝对的“是”或“否”,得结合你的操作场景来判断,但大部分情况下,合理使用requestAnimationFrame()确实能帮你避免不必要的性能损耗,不过也存在没必要甚至适得其反的场景。
先搞懂requestAnimationFrame()到底解决了什么问题
浏览器刷新屏幕的频率通常是60次/秒(也就是每~16.6ms一次),如果你的视觉变更操作没和这个周期同步,比如在一帧里多次修改DOM样式,浏览器可能会触发多次回流/重绘(这俩都是性能开销很大的操作),导致布局抖动、掉帧。
而requestAnimationFrame()的核心作用,就是让你的代码在浏览器即将开始重绘前执行——这样所有的视觉变更都会被批量处理,只触发一次回流/重绘,完美贴合浏览器的刷新节奏。
什么时候应该把所有视觉操作都包进去?
如果你的场景是连续、频繁的视觉更新,那必须用:
- 各类CSS/JS动画(比如元素移动、缩放、渐变)
- 滚动时的UI联动(比如导航栏吸顶、滚动触发的元素动画)
- 拖拽、实时数据可视化(比如仪表盘实时更新)
- 任何需要在短时间内重复修改DOM样式的操作
举个伪代码对比:
不用requestAnimationFrame()的情况(可能触发多次回流)
// 连续修改多个样式,浏览器可能每次改都触发一次回流 element.style.width = "100px"; element.style.height = "100px"; element.style.backgroundColor = "red";
用requestAnimationFrame()的情况(批量处理,只触发一次回流)
requestAnimationFrame(() => { element.style.width = "100px"; element.style.height = "100px"; element.style.backgroundColor = "red"; });
这种情况下,性能提升是很明显的,尤其是在复杂页面里,能有效避免掉帧。
什么时候没必要甚至不建议用?
如果是单次、低频的视觉变更,完全没必要包requestAnimationFrame():
- 点击按钮修改某个元素的颜色/显示状态
- 页面初始化时一次性设置一批样式
- 只修改一次DOM样式的操作
因为这类操作本身只会触发一次回流/重绘,包requestAnimationFrame()反而会让变更延迟一帧(最多~16.6ms),用户可能会感觉到轻微的滞后,得不偿失。
额外提醒
现在很多现代前端框架(比如React、Vue)内部已经实现了类似批量更新的机制,会自动把DOM变更攒到浏览器重绘前执行,所以在框架里手动加requestAnimationFrame()可能是重复操作,甚至可能引发问题。但如果你是用原生JS开发,上面的规则依然适用。
总结一下:连续高频的视觉更新用requestAnimationFrame(),单次低频的直接操作就行,这样既能保证性能,又不会牺牲用户体验。
内容的提问来源于stack exchange,提问作者lampshade

