当前位置: 首页 > article >正文

requestAnimationFrame(rAF)使用,与传统方法(如 setTimeout/setInterval),直观展示 rAF 的优势

目录

  • 核心优势
  • 适用场景
  • 案例对比(含代码)
    • 案例一:基础动画(方块移动)
    • 案例 2:高频更新(Canvas 粒子动画)
  • 总结

核心优势

  • 与浏览器渲染流程深度同步,避免无效计算
  • 自动暂停后台任务,节省资源
  • 减少布局抖动和重复渲染,提升复杂动画性能

适用场景

适用场景:所有需要高频更新视觉状态的动画、游戏、数据可视化等

案例对比(含代码)

案例一:基础动画(方块移动)

性能对比

指标setIntervalrAF
流畅度出现卡顿(丢帧)平滑稳定
实际效果方块移动不连贯方块匀速平滑移动

实际cpu占比情况和重绘的性能无明显差别
在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>rAF方块移动案例</title>
    <style>
        #box {
            width: 100px;
            height: 100px;
            background-color: red;
            position: absolute;
        }
    </style>
</head>
<body>
    <div id="box"></div>
</body>
<script>
    // const box = document.getElementById("box");
    // let position = 0;
    // function moveBox() {
    //     position += 2;
    //     box.style.left = position + "px";
    //     if (position >= 1000) {
    //         clearInterval(intervalId);
    //     }
    // }
    // const intervalId = setInterval(moveBox, 16); // 模拟 60FPS

    const box = document.getElementById("box");
    let position = 0;
    function moveBox() {
        position += 2;
        box.style.left = position + "px";
        if (position < 1000) {
            requestAnimationFrame(moveBox);
        }
    }
    requestAnimationFrame(moveBox);
</script>
</html>

案例 2:高频更新(Canvas 粒子动画)

性能对比

指标setIntervalrAF
帧率(FPS)帧率不稳定47-60 FPS稳定接近 60 FPS
GPU 占用优化后的绘制调用,GPU 压力更低

该案例下未感觉出明显的卡顿,内存相差不大,cpu较为明显
在这里插入图片描述

<!DOCTYPE html>
<html lang="zh">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>使用 requestAnimationFrame 的粒子动画</title>
    <style>
        canvas {
            border: 1px solid black;
        }
    </style>
</head>

<body>
    <canvas id="canvas" width="800" height="600"></canvas>
    <script>
        const canvas = document.getElementById("canvas");
        const ctx = canvas.getContext("2d");
        const particles = Array.from({ length: 1000 }, () => ({
            x: Math.random() * canvas.width,
            y: Math.random() * canvas.height,
            vx: Math.random() * 2 - 1,
            vy: Math.random() * 2 - 1,
        }));
        // 使用setTimeout实现动画
        function updateParticles() {
            ctx.clearRect(0, 0, canvas.width, canvas.height);
            particles.forEach((p) => {
                p.x += p.vx;
                p.y += p.vy;
                // 边界反弹
                if (p.x < 0 || p.x > canvas.width) p.vx *= -1;
                if (p.y < 0 || p.y > canvas.height) p.vy *= -1;

                ctx.fillRect(p.x, p.y, 2, 2);
            });
            setTimeout(updateParticles, 16);
        }
        updateParticles();

        // 使用requestAnimationFrame实现动画
        // function updateParticles() {
        //     ctx.clearRect(0, 0, canvas.width, canvas.height);
        //     particles.forEach((p) => {
        //         p.x += p.vx;
        //         p.y += p.vy;
        //         if (p.x < 0 || p.x > canvas.width) p.vx *= -1;
        //         if (p.y < 0 || p.y > canvas.height) p.vy *= -1;
        //         ctx.fillRect(p.x, p.y, 2, 2);
        //     });
        //     requestAnimationFrame(updateParticles);
        // }
        // requestAnimationFrame(updateParticles);
    </script>
</body>

</html>

总结

requestAnimationFrame 的核心优势是与浏览器渲染流程深度集成,通过减少无效渲染、自动节流、帧率同步等机制,显著提升动画性能


http://www.kler.cn/a/554586.html

相关文章:

  • C++:使用 SFML 创建强化学习迷宫场景
  • 计算机网络-OSI七层参考模型与数据封装,网络安全零基础入门到精通实战教程!
  • Spring Boot +SQL项目优化策略,GraphQL和SQL 区别,Spring JDBC 等原理辨析(万字长文+代码)
  • Python与Anaconda在CUDA环境中的角色解析
  • github在同步本地与远程仓库时遇到的问题
  • 6121A 音频分析仪
  • 网络运维学习笔记 015网工初级(HCIA-Datacom与CCNA-EI)NAT网络地址转换
  • 使用Java爬虫获取1688自定义API操作接口
  • 【Axure 模版素材】数据可视化驾驶舱+图表素材 - AxureMost
  • CPU与GPU之区别(The Difference between CPU and GPU)
  • 使用Geotools读取DEM地形数据实战-以湖南省30米数据为例
  • 网络安全-openssl工具
  • DeepSeek 助力 Vue 开发:打造丝滑的复制到剪贴板(Copy to Clipboard)
  • MacOS下使用Ollama本地构建DeepSeek并使用本地Dify构建AI应用
  • 基于springboot校园健康系统的设计与实现(源码+文档)
  • 解决“QString的split()函数分割中文“报错
  • 进程的延伸——线程(下)
  • 专利申请流程详解:从创意到授权的完整指南
  • 2025/2/19 心得
  • 开源软件的版权保护措施