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

使用requestAnimationFrame编写动画效果或者处理大量数据

一.什么是requestAnimationFrame:

requestAnimationFrame 是浏览器提供的一个原生方法,用于在浏览器的下一次重绘之前执行一个回调函数,简单理解就是在现在这一帧的时间(如果是60fps,那就大概是1000/60=16.6ms)内其他的东西已经执行完毕,就会执行这个函数,然后等这一帧的时间结束,又开始下一帧,一直循环。

它的核心作用是:在浏览器准备好重绘前自动调度回调函数,从而实现高性能动画效果。

二.基本使用方法:

1.基本语法:

let id = requestAnimationFrame(callback);

callback是执行的函数,浏览器会将当前帧的时间戳作为第一个参数传入;返回值id可以用于取消调用;

2.取消动画

cancelAnimationFrame(id);

三.使用场景:

1.用于绘制大量数据到页面上,可以避免页面卡顿

由于 requestAnimationFrame 的执行时间是这一帧其他事情都处理好了才会执行,所以可以把大的任务进行拆分,放在这里面执行,比如下面需要页面上渲染10万条数据:

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>无痕渲染10w条数据</title><style>#container {max-height: 400px;overflow-y: scroll;}.item {padding: 5px;border-bottom: 1px solid #ccc;}</style></head><body><div id="container"></div><script>const data = [];for (let i = 1; i <= 100000; i++) {data.push("Item" + i);}const container = document.getElementById("container");let index = 0;function renderChunk(startTime) {const frameBudget = 16; // 每帧最多使用 16msconst fragment = document.createDocumentFragment();while (index < data.length) {const div = document.createElement("div");div.textContent = data[index++];fragment.appendChild(div);// performance.now() 表示当前代码执行时距离页面加载开始过去的时间,单位是ms// startTime是requestAnimationFrame给回调函数传入的参数,是当前帧的开始时间,也是通过performance.now()获取的if (performance.now() - startTime > frameBudget) break;}container.appendChild(fragment);if (index < data.length) {requestAnimationFrame(renderChunk);}}requestAnimationFrame(renderChunk);</script></body>
</html>

通过这种分开渲染的方式,可以避免页面卡顿。

2.用于获取更精准的时间

相较于使用 setInterval 和 setTimeout 定时器来定时完成任务,requestAnimationFrame可以得到更精准的时间,因为代码本身执行是会消耗时间的,或者因为其他耗时任务的执行,都会影响到定时器中代码的执行时间,但是requestAnimationFrame不会,每次它的执行,都可以获取到最新的时间,以下是一个实时更新当前时间的代码:

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><title>获取当前时间</title></head><body><div id="time"></div><button onclick="cancelUpdate()">取消更新</button><script>let aniId = null;let updateTime = () => {let now = new Date();let hour = now.getHours().toString().padStart(2, "0");let minute = now.getMinutes().toString().padStart(2, "0");let second = now.getSeconds().toString().padStart(2, "0");let nowTime = `${hour}:${minute}:${second}`;document.getElementById("time").innerText = nowTime;aniId = requestAnimationFrame(updateTime);};updateTime()const cancelUpdate = () => {cancelAnimationFrame(aniId);};</script></body>
</html>
http://www.xdnf.cn/news/9198.html

相关文章:

  • 时序数据库IoTDB安装学习经验分享
  • 第三届全国先进技术成果转化大会成功举办 中科亿海微携品亮相
  • 【premiere教程】【01】【跑个流程】
  • 【android bluetooth 协议分析 02】【bluetooth hal 层详解 6】【高通蓝牙hal主要流程介绍-下】
  • Java 基础全面解析
  • Kettle 远程mysql 表导入到 hadoop hive
  • WPF【11_7】WPF实战-重构与美化(ViewModel的嵌套与分解、海量数据不要Join)
  • OpenCV CUDA模块图像处理------颜色空间处理之GPU 上对两张带有 Alpha 通道的图像进行合成操作函数alphaComp()
  • 【洛谷P9303题解】AC代码- [CCC 2023 J5] CCC Word Hunt
  • ubuntu22.04 安装 SecureCRT8.7.3
  • 没有经验能考OCP认证吗?
  • 视频逐帧提取图片的工具
  • 拆解汽车HMI设计:如何用3D可视化提升驾驶安全感?
  • RagFlow参数配置测试
  • 2025.5.27学习日记 linux三剑客 sed与正则表达式
  • 安卓开发用到的设计模式(3)行为型模式
  • Day31 -js应用 -实例:webpack jQuery的使用及其隐含的安全问题
  • C语言-指针
  • 目前可用随时更新,8种使用Claude4的方法!
  • 跨协议协同智造新实践:DeviceNet-EtherCAT网关驱动汽车焊接装配效能跃迁
  • word里面如何保存高清图片
  • idea 控制台 彩色打印日志
  • 主键与唯一键详解:概念、区别与面试要点
  • 【Bluedroid】init_stack_internal 函数全流程源码解析
  • Qt 多线程环境下的全局变量管理与密码安全
  • 电路图识图基础知识-主电路和辅助电路(七)
  • 华为FreeArc能和其他华为产品共用充电线吗?
  • C# 变量与常量完全指南:从基础到高级应用
  • 融智学“新五常”框架:五维方式的重构与协同
  • 十一、Samba文件共享服务