返回顶部
首页 > 资讯 > 前端开发 > JavaScript >如何计算Web动画帧率FPS
  • 615
分享到

如何计算Web动画帧率FPS

2024-04-02 19:04:59 615人浏览 八月长安
摘要

目录流畅动画的标准法一:借助 Chrome 开发者工具法二:借助 Frame Timing apiBlink 内核早期架构js 动画与 CSS 动画的细微区别什么是 Frame Ti

流畅动画的标准

首先,理清一些概念。FPS 表示的是每秒钟画面更新次数。我们平时所看到的连续画面都是由一幅幅静止画面组成的,每幅画面称为一帧,FPS 是描述“帧”变化速度的物理量。

理论上说,FPS 越高,动画会越流畅,目前大多数设备的屏幕刷新率为 60 次/秒,所以通常来讲 FPS 为 60 frame/s 时动画效果最好,也就是每帧的消耗时间为 16.67ms。

当然,经常玩 FPS 游戏的朋友肯定知道,吃鸡/CSGo 等 FPS 游戏推荐使用 144HZ 刷新率的显示器,144Hz 显示器特指每秒的刷新率达到 144Hz 的显示器。相较于普通显示器每秒60的刷新速度,画面显示更加流畅。因此144Hz显示器比较适用于视角时常保持高速运动的第一人称射击游戏。

不过,这个只是显示器提供的高刷新率特性,对于我们 WEB 动画而言,是否支持还要看浏览器,而大多数浏览器刷新率为 60 次/秒。

直观感受,不同帧率的体验:

  • 帧率能够达到 50 ~ 60 FPS 的动画将会相当流畅,让人倍感舒适;
  • 帧率在 30 ~ 50 FPS 之间的动画,因各人敏感程度不同,舒适度因人而异;
  • 帧率在 30 FPS 以下的动画,让人感觉到明显的卡顿和不适感;
  • 帧率波动很大的动画,亦会使人感觉到卡顿。

OK,那么我们该如何准确的获取我们页面动画当前的 FPS 值呢?

法一:借助 Chrome 开发者工具

Chrome 提供给开发者的功能十分强大,在开发者工具中,我们进行如下选择调出FPS meter选项:

通过这个按钮,可以开启页面实时 Frame Rate (帧率) 观测及页面 GPU 使用率。

缺点:

  • 这个只能一次观测一到几个页面,而且需要人工实时观测
  • 数据只能是主观感受,并没有一个十分精确的数据不断上报或者被收集

因此,我们需要更加智能的方法。

法二:借助 Frame Timing API

在介绍下面这种方法前,继续做一些基础知识的科普。

Blink 内核早期架构

以 Chrome 浏览器内核 Blink 渲染页面为例。对早期的 Chrome 浏览器而言,每个页面 Tab 对应一个独立的 renderer 进程,Renderer 进程中包含了主线程和合成线程。早期 Chrome 内核架构:

其中,主线程主要负责:

  • javascript 的计算与执行
  • CSS 样式计算
  • Layout 计算
  • 将页面元素绘制成位图(paint),也就是光栅化(Raster)
  • 将位图给合成线程

合成线程则主要负责:

  • 将位图(GraphicsLayer 层)以纹理(texture)的形式上传给 GPU
  • 计算页面的可见部分和即将可见部分(滚动)
  • CSS 动画处理
  • 通知 GPU 绘制位图到屏幕上

OK,云里雾里的,什么东西。其实知道了这两个线程之后,下一个概念是厘清 CSS 动画与 JS 动画的细微区别(当然它们都是 Web 动画)。

JS 动画与 CSS 动画的细微区别

对于 JS 动画而言,它们运行时的帧率即是主线程和合成线程加起来消耗的时间。对于流畅动画而言,我们希望它们每一帧的耗时保持在 16.67ms 之内;

而对于 CSS 动画而言,由于其流程不受主线程的影响,所以希望能得到合成线程的消耗的时间,而合成线程的绘制频率也反映了滚动和 CSS 动画的流程性。

上面主要想得出的一个结论是。如果我们能够知道主线程和合成线程每一帧消耗的时间,那么我们就能大致得出对应的 Web 动画的帧率。那么上面说到的Frame Timing API是否可以帮助我们拿到这个时间点呢。

什么是 Frame Timing API ?

Frame Timing API 是 Web PerfORMance Timing API 标准中的其中一位成员。

Web Performance Timing API是 W3C 推出的一套性能API 标准,用于帮助开发者对网站各方面的性能进行精确的分析与控制,提升 Web 网站性能。

它包含许多子类 API,完成不同的功能,大致如下(摘自使用性能API快速分析web前端性能,当然你也可以看英文原版介绍:Web Performance Timing API):

怎么使用呢?以Navigation Timing, Performance Timeline, Resource Timing为例子,对于兼容它的浏览器,它以只读属性的形式对外暴露挂载在window.performance上。

在调试台 console 中打印window.performance,查看其中的 timing 属性:

这对象内一连串的变量表示什么呢,它表示我们页面整个加载过程中每一个重要的时间点,可以详细看看这张图:

通过这张图以及上面的window.performance.timing,我们就可以轻松的统计出页面每个重要节点的耗时,这就是Web Performance Timing API的强大之处,感兴趣的可以详细去研究研究,使用在页面统计上。

Frame Timing API 示意

好的,终于可以回归正题,借助Web Performance Timing API中的Frame Timing API,可以轻松的拿到每一帧中,主线程以及合成线程的时间。或者更加容易,直接拿到每一帧的耗时。

获取 Render 主线程和合成线程的记录,每条记录包含的信息基本如下,代码示意,(参考至Developer feedback needed: Frame Timing API):


var rendererEvents = window.performance.getEntriesByType("renderer");
var compositeThreadEvents = window.performance.getEntriesByType("composite");

或者是:


var observer = new PerformanceObserver(function(list) {
    var perfEntries = list.getEntries();
    for (var i = 0; i < perfEntries.length; i++) {
        console.log("frame: ", perfEntries[i]);
    }
});
 
// subscribe to Frame Timing
observer.observe({entryTypes: ['frame']});

每条记录包含的信息基本如下:


{
  sourceFrameNumber: 120,
  startTime: 1342.549374253
  cpuTime: 6.454313323
}

每个记录都包括唯一的 Frame Number、Frame 开始时间以及 cpuTime 时间。通过计算每一条记录的 startTime ,我们就可以算出每两帧间的间隔,从而得到动画的帧率是否能够达到 60 FPS。

不过!看看Web Performance Timing API整体的兼容性:

Frame Timing API 虽好,但是,现在Frame Timing API的兼容性不算很友好,额,不友好到什么程度呢。还没有任何浏览器支持,处于实验性阶段,属于面向未来编程。这你 TM 逗我呢?说了这么久完全不能用.....

法三:借助 requestAnimationFrame API

费了这么多笔墨描述 Frame Timing API 但最后因为兼容性问题完全没办法使用。不过不代表这么长篇幅的描述没有用,从上面的介绍,我们得知,如果我们可以到得到每一帧中的固定一个时间点,那么两者相减,也能够近似得到一帧所消耗的时间。

那么,我们再另辟蹊径。这次,我们借助兼容性不错的 requestAnimationFrame API。


// 语法
window.requestAnimationFrame(callback);

requestAnimationFrame大家应该都不陌生,方法告诉浏览器您希望执行动画并请求浏览器调用指定的函数在下一次重绘之前更新动画。

当你准备好更新屏幕画面时你就应用此方法。这会要求你的动画函数在浏览器下次重绘前执行。回调的次数常是每秒 60 次,大多数浏览器通常匹配 W3C 所建议的刷新率。

使用 requestAnimationFrame 计算 FPS 原理

原理是,正常而言 requestAnimationFrame 这个方法在一秒内会执行 60 次,也就是不掉帧的情况下。假设动画在时间 A 开始执行,在时间 B 结束,耗时 x ms。而中间 requestAnimationFrame 一共执行了 n 次,则此段动画的帧率大致为:n / (B - A)。

核心代码如下,能近似计算每秒页面帧率,以及我们额外记录一个 allFrameCount,用于记录 rAF 的执行次数,用于计算每次动画的帧率 :


var rAF = function () {
    return (
        window.requestAnimationFrame ||
        window.webkitRequestAnimationFrame ||
        function (callback) {
            window.setTimeout(callback, 1000 / 60);
        }
    );
}();
  
var frame = 0;
var allFrameCount = 0;
var lastTime = Date.now();
var lastFameTime = Date.now();
  
var loop = function () {
    var now = Date.now();
    var fs = (now - lastFameTime);
    var fps = Math.round(1000 / fs);
  
    lastFameTime = now;
    // 不置 0,在动画的开头及结尾记录此值的差值算出 FPS
    allFrameCount++;
    frame++;
  
    if (now > 1000 + lastTime) {
        var fps = Math.round((frame * 1000) / (now - lastTime));
        console.log(`${new Date()} 1S内 FPS:`, fps);
        frame = 0;
        lastTime = now;
    };
  
    rAF(loop);
}
 
loop();

OK,寻找一个有动画不断运行的页面进行测试,可以看到代码运行如下:

这里,我使用了我之前制作的一个页面进行了测试,使用 Chrome 同时调出页面的 FPS meter,对比两边的实时 FPS 值,基本吻合。

测试页面,Solar System。你可以将上面的代码贴到这个页面的 console 中,测试一下数据:

对比右上角的 Frame Rate,帧率基本一致。在大部分情况下,这种方法可以很好的得出 Web 动画的帧率。

如果我们需要统计某个特定动画过程的帧率,只需要在动画开始和结尾两处分别记录allFrameCount这个数值大小,再除以中间消耗的时间,也可以得出特定动画过程的 FPS 值。

值得注意的是,这个方法计算的结果和真实的帧率肯定是存在误差的,因为它是将每两次主线程执行 javascript 的时间间隔当成一帧,而非上面说的主线程加合成线程所消耗的时间为一帧。但是对于现阶段而言,算是一种可取的方法。

以上就是如何计算Web动画帧率FPS的详细内容,更多关于计算Web动画帧率FPS的资料请关注编程网其它相关文章!

--结束END--

本文标题: 如何计算Web动画帧率FPS

本文链接: https://lsjlt.com/news/126693.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 如何计算Web动画帧率FPS
    目录流畅动画的标准法一:借助 Chrome 开发者工具法二:借助 Frame Timing APIBlink 内核早期架构JS 动画与 CSS 动画的细微区别什么是 Frame Ti...
    99+
    2024-04-02
  • javascript如何实现帧动画
    小编给大家分享一下javascript如何实现帧动画,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!概述【分类】常见的帧动画的方式...
    99+
    2024-04-02
  • 如何用CSS3实现帧动画
    本文小编为大家详细介绍“如何用CSS3实现帧动画”,内容详细,步骤清晰,细节处理妥当,希望这篇“如何用CSS3实现帧动画”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。代码:定义一...
    99+
    2024-04-02
  • Android Studio如何实现帧动画
    这篇文章主要讲解了“Android Studio如何实现帧动画”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Android Studio如何实现帧动画”吧!按一定的顺序播放静态的图片几张联系...
    99+
    2023-06-25
  • 关于mmdetection、mmrotate如何计算参数量、计算量和速度FPS
    近几天跑完实验后,发现效果还是不错,于是开始进行模型的参数量、计算量和速度指标的计算对比,话不多说,直接上干货。 ---------------------------------------------------------------...
    99+
    2023-10-20
    python pytorch 深度学习
  • iOS如何实现逐帧动画做loading视图
    这篇文章给大家分享的是有关iOS如何实现逐帧动画做loading视图的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。具体内容如下我封装了一个可复用的loading视图组件,用于按照一定周期逐帧播放加载动画。代码如下...
    99+
    2023-06-15
  • 如何使用CSS制作文字实现逐帧动画
    这篇文章主要介绍了如何使用CSS制作文字实现逐帧动画,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。方法步骤HTML部分1、创建html定义一...
    99+
    2024-04-02
  • pandas如何提升计算效率
    这篇文章给大家分享的是有关pandas如何提升计算效率的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。前言Pandas是为一次性处理整个行或列的矢量化操作而设计的,循环遍历每个单元格、行或列并不是它的设计用途。所以...
    99+
    2023-06-15
  • Python pandas如何计算每行的增长率与累计增长率
    小编给大家分享一下Python pandas如何计算每行的增长率与累计增长率,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!读取数据:FacebookDf=pd.read_excel(r'D:\jupyte...
    99+
    2023-06-29
  • HTML5中如何使用requestAnimationFrame优化Web动画
    这篇文章主要介绍了HTML5中如何使用requestAnimationFrame优化Web动画,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。...
    99+
    2024-04-02
  • web开发如何实现移动端下拉加载动画
    这篇文章给大家分享的是有关web开发如何实现移动端下拉加载动画的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。  <!DOCTYPE html> &...
    99+
    2024-04-02
  • 如何使用VBS计算中文姓名笔画
    这篇文章将为大家详细讲解有关如何使用VBS计算中文姓名笔画,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。代码如下:'中文姓名笔画计算(VBS脚本版) dim word,key word=input...
    99+
    2023-06-08
  • PyTorch 如何自动计算梯度
    在PyTorch中,torch.Tensor类是存储和变换数据的重要工具,相比于Numpy,Tensor提供GPU计算和自动求梯度等更多功能,在深度学习中,我们经常需要对函数求梯度(...
    99+
    2024-04-02
  • js如何实现酷炫倒计时动画
    这篇“js如何实现酷炫倒计时动画”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“js如何实现酷炫倒计时动画”文章吧。<!...
    99+
    2023-07-02
  • Windows下的分布式计算:如何提高效率?
    随着计算机技术的发展和计算能力的不断提高,分布式计算已经成为了现代计算机领域中的一个热门话题。在这篇文章中,我们将介绍如何在Windows操作系统下使用分布式计算技术,以提高计算效率。 一、分布式计算的概念和基础知识 分布式计算是指将一个...
    99+
    2023-10-14
    分布式 windows numpy
  • 如何在html5中自动计算fontSize
    本篇文章为大家展示了如何在html5中自动计算fontSize,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。具体如下:var winWidth = window.inn...
    99+
    2023-06-09
  • 如何使用纯js + transition动画实现移动端web轮播图
    这篇文章主要介绍了如何使用纯js + transition动画实现移动端web轮播图,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带...
    99+
    2024-04-02
  • PyTorch怎么如何自动计算梯度
    小编给大家分享一下PyTorch怎么如何自动计算梯度,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!在PyTorch中,torch.Tensor类是存储和变换数据的...
    99+
    2023-06-15
  • 效率的巅峰:分时操作系统如何提升计算机利用率
    提高吞吐量 分时操作系统通过提高计算机吞吐量来提高利用率。吞吐量是指计算机在给定时间内执行的任务数量。通过允许多个用户同时执行任务,分时操作系统可以提高吞吐量,因为一个用户在等待进行输入或输出操作时,另一个用户可以使用 CPU。 减少响应...
    99+
    2024-03-15
    分时操作系统
  • IDE中的Python NumPy:如何提高分布式计算效率?
    Python NumPy是一个用于数值计算的Python库,它提供了高效的多维数组操作功能,并且拥有丰富的数学函数库。作为一个广泛应用于科学计算和数据分析领域的工具,Python NumPy在分布式计算方面也有着重要的作用。 在分布式计算中...
    99+
    2023-10-30
    numpy 分布式 ide
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作