详细学习 requestAnimationFrame —— 浏览器动画的“正确打开方式”

写个人博客时,想实现一个雪花飘落的动画效果,一开始用的是setInterval来不断执行动画,但是发现动画会卡顿,后来找资料发现有个更好用的函数,于是写下这篇比较详细的学习博客

一、什么是 requestAnimationFrame

requestAnimationFrame 是浏览器提供的一个 原生 API,用于在浏览器下一次重绘(repaint)之前执行 JavaScript 回调函数。

它是进行 高性能动画渲染 的首选方式。

const id = requestAnimationFrame(callback);
  • 浏览器每次屏幕刷新时都会调用一次回调(大多数显示器是 60Hz,即每秒 60 帧,约 16.7ms 一次)

  • 不会主动控制时间间隔,而是将你注册的回调交由浏览器统一调度

  • 自动与浏览器渲染时机同步,防止掉帧

二、浏览器渲染流程简析

理解 rAF 的最佳方式是先理解浏览器的 渲染帧机制

一次完整的帧流程(16.7ms)如下: 事件处理 -> requestAnimationFrame -> 样式计算 -> 布局 -> 绘制 -> 合成 -> 显示

💡 requestAnimationFrame 的调用时机:在样式计算和布局之前执行!

这意味着:你可以在回调中修改 DOM,浏览器会使用这些最新变动来进行后续布局和绘制,从而实现平滑过渡

三、requestAnimationFrame的参数

requestAnimationFrame 是一个使用非常简单但功能强大的 API。它本身只接收一个参数,但是这个参数是一个 带有内置传参的回调函数,但是它的回调函数会有一个参数

requestAnimationFrame(function(timestamp) {
  console.log(timestamp);
});

timestamp 是什么?

名称类型含义
timestampDOMHighResTimeStamp当前帧执行回调时的时间戳(以毫秒为单位,高精度小数

 

使用例子:

let startTime;
function step(timestamp) {
  if (!startTime) startTime = timestamp;
  const progress = timestamp - startTime;
  box.style.left = Math.min(progress / 10, 200) + 'px';
  if (progress < 2000) {
    requestAnimationFrame(step);
  }
}
requestAnimationFrame(step);

是不是有点看不懂,其实这段代码的整体作用是:

 在 2 秒内,让一个 DOM 元素 box 从当前位置平滑地向右移动 最多 200px

  • 控制动画持续时间:progress < 2000

  • 控制动画移动距离:Math.min(..., 200)

  • 使用 requestAnimationFrame 实现高性能、掉帧补偿的自然动画

 

四、requestAnimationFrame vs setTimeout / setInterval

特性requestAnimationFramesetTimeout / setInterval
是否跟屏幕刷新同步✅ 是(与显示器刷新率同步)❌ 否(固定间隔,可能跳帧)
节能优化✅ 是(处于后台标签页时自动暂停)❌ 否(后台仍继续执行)
平滑度✅ 动画自然,防止卡顿❌ 容易卡顿、动画不连贯
调度顺序✅ 每帧绘制前调用,紧跟渲染周期❌ 调度不固定,可能在绘制后执行
控制方式基于浏览器调度,无需手动设置间隔需手动设置延迟时间,如 setTimeout(fn, 16)

五.相比之下requestAnimationFrame 的优点

优点说明
同步刷新率与屏幕刷新一致(一般 60FPS),动画更流畅
节能优化标签页不活跃时自动暂停,节省资源
高精度时间戳内置 timestamp,便于控制动画进度
性能更好优先级高,避免掉帧,浏览器可优化渲染
自动调帧率不需手动设置间隔,帧率智能控制

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值