requestAnimationFrame性能测试

news2024/10/7 8:29:24

requestAnimationFrame:每次重绘最多只调用一次回调函数
测试开启/关闭requestAnimationFrame的监听事件调用次数差异:
先说结论:存在约8倍的调用次数差距!

requestAnimationFrame使用与否的次数差距

本次测试代码为drag事件

const source = document.getElementById("draggable");
    let enqueued = false
    let times = 0
    source.addEventListener("drag", (event) => {
    });

    let timeNow = null;
    source.addEventListener("dragstart", (event) => {
        if(!enqueued) {
            timeNow = new Date();
        }
    });    
    const target = document.getElementById("droptarget");
    target.addEventListener("dragover", (event) => {
        // if (!enqueued) {
        //     enqueued = true
        //     requestAnimationFrame(() => {
                // console.log(event);
                console.log(times++);
                // enqueued = false
        //     })
        // }
        event.preventDefault();
    }, false);
        target.addEventListener("drop", (event) => {
        console.log('done');
        console.log(new Date() - timeNow);
    });

不开启requestAnimationFrame,测试drag次数:

请添加图片描述

请添加图片描述
请添加图片描述
请添加图片描述

请添加图片描述
这是未开启requestAnimationFrame的dragstart到drop时间间隔内的 dragover次数,它们次数/时间间隔分别为:0.4997、0.4705、0.4550、0.5110、0.4148。
平均为:0.4761

const source = document.getElementById("draggable");
    let enqueued = false
    let times = 0
    source.addEventListener("drag", (event) => {
    });

    let timeNow = null;
    source.addEventListener("dragstart", (event) => {
        if(!enqueued) {
            timeNow = new Date();
        }
    });    
    const target = document.getElementById("droptarget");
    target.addEventListener("dragover", (event) => {
        if (!enqueued) {
            enqueued = true![请添加图片描述](https://img-blog.csdnimg.cn/96613896661944738b1deb7e85b07796.png)

            requestAnimationFrame(() => {
                console.log(event);
                console.log(times++);
                enqueued = false
            })
        }
        event.preventDefault();
    }, false);
    target.addEventListener("drop", (event) => {
        console.log('done');
        console.log(new Date() - timeNow);
    });

请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
加上requestAnimationFrame之后他们的次数/时间间隔为:
0.0597、0.0592、0.0596、0.0581、0.0595
平均为:0.0592

前后差距:0.4761/0.0592约等于8倍的调用次数差距!

requestAnimationFrame与settimeout、setinterval的区别

无论 setInterval()还是 setTimeout()都是不能保证时间精度的。

作为第二个参数的延时 只能保证何时会把代码添加到浏览器的任务队列,不能保证添加到队列就会立即运行。如果队列前面还有其他任务,那么就要等这些任务执行完再执行。简单来讲,这里毫秒延时并不是说何时这些代码会执 行,而只是说到时候会把回调加到任务队列。如果添加到队列后,主线程还被其他任务占用,比如正在 处理用户操作,那么回调就不会马上执行。

requestAnimationFrame()方法接收一个参数,此参数是一个要在重绘屏幕前调用的函数。

它解决了浏览器不知道 JavaScript 动画何时开始的问题, 以及最佳间隔是多少的问题。
传给 requestAnimationFrame()的函数实际上可以接收一个参数,此参数是一个 DOMHighRes- TimeStamp 的实例(比如 performance.now()返回的值),表示下次重绘的时间。这一点非常重要: requestAnimationFrame()实际上把重绘任务安排在了未来一个已知的时间点上,而且通过这个参数 告诉了开发者。基于这个参数,就可以更好地决定如何调优动画了。

与 setTimeout()类似,requestAnimationFrame()也返回一个请求 ID,可以用于通过另一个 方法 cancelAnimationFrame()来取消重绘任务。

let requestID = window.requestAnimationFrame(() => {
  console.log('Repaint!');
})
window.cancelAnimationFrame(requestID);

requestAnimationFrame如何实现节流

支持这个方法的浏览器实际上会暴露出作为钩子的回调队列。所谓钩子(hook),就是浏览器在执行下一次重绘之前的一个点。这个回调队列是一个可修改的函数列表,包含应该在重绘之前调用的函数。每次调用 requestAnimationFrame()都会在队列上推入一个回调函数,队列的长度没有限制。

可以保证每次重绘最多只调用一次回调函数。这是一个非常好的节流工具。在频繁执行影响页面外观的代码时(比如滚动事件监听器),可以利用这个回调队列进行节流。例如上文的代码

但是重绘是非常频繁的操作,所以加上requestAnimationFrame之后还不算真正的节流,需要配合定时器

 let enabled = true;
 function expensiveOperation() {
      console.log('Invoked at', Date.now());
 }
 window.addEventListener('scroll', () => {
 if (enabled) {
     enabled = false;
     window.requestAnimationFrame(expensiveOperation);
     window.setTimeout(() => enabled = true, 50);
 }
});

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/743883.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Pycharm设置Python文件页眉默认信息(作者姓名、创建时间等)

次点击File->Settings->Editor->File and Code Templates->然后选择Python script. 后将下列代码复制到右边的框框中,然后选择apply应用,就可以啦 ##!/usr/bin/python3 # -*- coding: utf-8 -*- # Time : ${DATE} ${TIME} # Author : 作者…

【CSS加载动画特效】28种纯CSS实现的加载loading动态特效(附源码)

文章目录 写在前面涉及知识点效果展示1、Loading节点的创建2、部分效果的实现源码1)三点加载动画Html代码CSS样式代码 2)圆点矩阵加载特效Html代码CSS样式代码 3)圆形轨迹加载动画Html代码Css样式代码 4)栅栏式加载动画Html代码Cs…

Qt/C++音视频开发46-音视频同步保存到MP4

一、前言 用ffmpeg单独做视频保存不难,单独做音频保存也不难,难的是音视频同步保存到MP4中,重点是音视频要同步,其实这也不难,只要播放那边音视频同步后的数据,写入到文件即可。最难的是在播放过程中不断随…

python对dataframe索引的操作

目录 假如有个dataframe如下,这里需要去除第一个aa,保留最后一个aa 关键代码 # 如果你想保留第一个aa,那么keep就是first df.reset_index().drop_duplicates(subsetindex, keepfirst).set_index(index)结果如下: 原文链接&am…

10.1.5 查询指令是否为 Bash shell 的内置命令: type

通过 type 这个指令我们可以知道每个指令是否为 bash 的内置指令。 此外,由于利用 type 搜寻后面的名称时,如果后面接的名称并不能以可执行文件的状态被找到, 那么该名称是不会被显示出来的。也就是说, type 主要在找出“可执行文…

3 Prometheus安装

目录 1. 安装Prometheus 2. 基于linux安装Prometheus 下载安装包 将安装包放在合适的目录下 启动prometheus 访问 3. 配置Prometheus 3.1 global 3.2 alerting 3.3 rule_files 3.4 static_configs 4. 第一个指标 5 表达式浏览器 指标列表自动填充 指标名称筛选 指…

pytorch的whl文件安装

下载.whl文件,离线安装 提示:下载torch的稳定版本网址[https://download.pytorch.org/whl/torch_stable.html](https://download.pytorch.org/whl/torch_stable.html) 首先,查看主机显卡和安装的cuda版本。 可以在命令行输入:nvcc -V 如果…

使用jquery遇到的问题Unresolved function or method $()

今天在使用jquery的时候,发现页面中即使引入了jquery.min.js,js代码中仍然说找不到$(),原来的项目也是用的jquery.min.js,为什么之前的就没有这个问题呢。 然后利用搜索引擎查了一下解决方案,最后还是决定改成未压缩版…

触摸按键控制LED灯亮灭

文章目录 前言一、触摸按键介绍二、触摸按键电路原理模式一:模式二: 三、系统设计1、模块框图2、RTL视图 四、源码1、touch_led模块 五、效果六、总结七、参考资料 前言 环境: 1、Quartus18.1 2、vscode 3、板子型号:原子哥开拓者…

前端熟练发起ajax请求的多种方法

1.原生发起ajax 1.1概念: 说明:XMLHttpRequest是 JavaScript 的内置对象,用于在Web应用程序中向服务器发送HTTP请求和接收响应。通过XMLHttpRequest对象,可以实现异步加载数据,无需刷新整个页面即可更新部分内容。常…

Ubuntu 22.04 LTS RTX 2060 6G 显卡 GPU测试 甜甜圈 geeks3d GpuTest

下载 GpuTest主页地址 GpuTest - Cross-Platform GPU Stress Test and OpenGL Benchmark for Windows, Linux and OS X | Geeks3D.com 下载页 GpuTest download | Geeks3D 下载链接 https://ozone3d.net/gputest/dl/GpuTest_Linux_x64_0.7.0.zip 测试 unzip GpuTest_Li…

【C#】并行编程实战:同步原语(上)

在第4章中讨论了并行编程的潜在问题,其中之一就是同步开销。当将工作分解为多个工作项并由任务处理时,就需要同步每个线程的结果。线程局部存储和分区局部存储,某种程度上可以解决同步问题。但是,当数据共享时,就需要用…

Python实现PSO粒子群优化算法优化XGBoost回归模型(XGBRegressor算法)项目实战

说明:这是一个机器学习实战项目(附带数据代码文档视频讲解),如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 PSO是粒子群优化算法(Particle Swarm Optimization)的英文缩写,是一…

在线培训系统成为未来自主学习利器

传统教育模式存在的一个重要问题是,学生往往需要跟随教师和课堂的步调前进。这种模式可能会导致一些学生在学习过程中感到压力和挫败,并且不可避免地会出现部分学生落后于其他同学的情况。然而,在线培训系统可以赋予学生更多的自主权&#xf…

Linux系统编程(环境变量编程)

文章目录 前言一、环境变量表二、环境变量读写接口总结 前言 本篇文章我们来讲解环境变量编程,环境变量在Linux中可以说是非常重要的,那么这篇文章将会带大家来学习环境变量的编程。 一、环境变量表 在Linux系统中,环境变量是一种特殊的变…

SQL-每日一题【595.大的国家】

题目 World 表: 如果一个国家满足下述两个条件之一,则认为该国是 大国 : 面积至少为 300 万平方公里(即,3000000 km2),或者人口至少为 2500 万(即 25000000) 编写一个…

kafka第一课-Kafka快速实战以及基本原理详解

一、Kafka介绍 Kafka是一个分布式的发布-订阅消息系统,可以快速地处理高吞吐量的数据流,并将数据实时地分发到多个消费者中。Kafka消息系统由多个broker(服务器)组成,这些broker可以在多个数据中心之间分布式部署&…

react学习笔记——复习模块

前言:最近开始学习react,之前学习vue没有把笔记整理的特别好,非常后悔,感觉学了等于没学,这次要好好整理啊!本次学习参考教程为B站,张天禹老师的react全家桶。 文章目录 类的基本知识创建一个类…

时间序列分类 论文和数据集汇总

时间序列分类 时间序列广泛应用于金融、工业领域、健康、运维、交通领域。 其实异常检测任务也可以看作是一个时间序列分类任务,异常与否两类,或者异常有很多种,则是多分类问题。 时间序列分类的数据是多种的:时间轨迹数据&#x…

Real-time Short Video Recommendation on Mobile Devices 阅读笔记

摘要 用户会实时兴趣转移,为实现在客户端重排,提出一种 context-aware re-ranking 方法,基于 adaptive beam search 1 引言 1.1 之前架构的问题: 1,需解决 real-time feedback 的问题 2,速度问题 1.2…