JavaScript 动画实现 requestAnimationFrame 用法

本文对比了CSS动画、setInterval及requestAnimationFrame实现动画的效果与性能。requestAnimationFrame跟随浏览器刷新频率,避免卡顿,节省CPU资源,尤其适合高频事件处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

JavaScript 动画实现 requestAnimationFrame 用法

动画对比

  1. CSS 动画
    在浏览器端实现动画(不进行重绘的前提下),首选是使用 CSS 的 transition 属性和animation 属性。因为其使用 compositor thread 绘制,与主线程 main thread 同时进行,不会阻塞主线程。但是 CSS 动画的一大弊端是无法使用函数,也就是没法根据参数实现动态动画。

  2. setInterval 或 setTimeout 实现动画
    JS 绘制动画主要通过定时器 setInterval 函数和 setTimeout 函数。这两个函数可以实现很多灵活的动画。但是他们也有一个问题,就是动画容易卡顿,其原因在于定时器绘制的时间与帧响应(每秒的刷新频率,最佳为1000/60≈16.67)的时间没法百分百保持同步。

  3. requestAnimationFrame 实现动画
    requestAnimationFrame 是请求动画帧,其实现原理是会把每一帧中的所有 DOM 操作集中起来,在一次重绘或回流中就完成,其间隔紧紧跟随浏览器的刷新频率(屏幕上的图像每秒钟出现的次数),一般来说,这个频率为每秒60帧。另外,在隐藏或不可见的元素中,requestAnimationFrame 将不会进行重绘或回流,这就意味着更少的 cpu 与 gpu 内存消耗。

    而且对于高频事件(比如 scroll 事件)来说,使用 requestAnimationFrame 也能很好地节流。高频事件有可能不止 16.67ms 更新一次。但是高频率的刷新显示屏是察觉不到的,所以使用 requestAnimationFrame 可以节省函数执行的开销。

案例

实现元素向右移动。

  1. setInterval
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<style>
</style>
<body>
<div id="div" style="background: pink;width: 100px;height: 100px;position: relative"></div>
</body>
<script>
    var div = document.getElementById('div');
    var dis = 0,timer = 0;
    clearInterval(timer);
    timer = setInterval(function(){
        div.style.left = ++dis+"px";
        if(dis>=50) clearInterval(timer)
    },16);
</script>
</html>
  1. requestAnimationFrame
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<style>
</style>
<body>
<div id="div" style="background: pink;width: 100px;height: 100px;position: relative"></div>
</body>
<script>
    var div = document.getElementById('div');
    var dis =0;
    function animation(){
        requestAnimationFrame(function(){
            div.style.left = ++dis+"px";
            if(dis<50) animation();
        })
    }
    animation();
</script>
</html>

分析

使用 setInterval 函数实现动画是写死的每 16ms 更新一次,但是系统更新时间有可能不只16ms 或者多余 16ms,那么再次刷新的时候就会卡顿,因为上一个动画还没执行完或者丢帧。
而使用 requestAnimationFrame 写的动画不需要写时间,它是由系统来决定回调函数的执行时机。跟随浏览器的刷新频率。所以不会出现卡顿或者丢帧的现象。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值