首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >以编程方式测量画布动画的性能

以编程方式测量画布动画的性能
EN

Stack Overflow用户
提问于 2013-10-01 16:00:43
回答 3查看 1.8K关注 0票数 2

我正在为JavaScript性能竞赛构建一个测试平台。其中一项任务要求参赛者优化负责处理画布动画的JavaScript代码。提交解决方案后,服务器使用PhantomJS运行它,并在20秒的动画后读取FPS的平均数量。问题是,我得到了3-4FPS的优化和未优化的代码。这使得无法判断代码是否得到了改进。

几个事实:

  • 我100%确信幻影动画渲染正确(做了几个截图)
  • 在浏览器中,未优化的代码运行在13 runs,优化运行在58 runs。
  • 幻影不支持requestAnimationFrame,所以我不得不使用聚脂填充
  • 我正在使用下面的代码来测试FPS的数量

frameCounter.js

代码语言:javascript
复制
 var frameCounter = (function() {
    var frames = 0;
    var startTime = new Date();

    function bump() {
        frames++;
        window.requestAnimationFrame(bump);
    }

    bump();

    return {
        getFPS: function() {
            var time = (new Date() - startTime) / 1000;

            return (frames/time).toPrecision(4);
        }
    }
 })();

我的问题是:如何以编程方式衡量画布动画的性能?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-10-18 07:59:20

由于幻影似乎无法在任何动画上产生超过3-4个FPS,所以我最终使用了“真正的”浏览器来完成这项任务。多亏了Chrome的远程调试协议,我才能实现它的自动化。

我制作了一个node.js应用程序,每次需要测试新代码时,执行以下步骤:

  • 连接到Chrome浏览器中的一个选项卡(浏览器必须使用--remote-debugging-port=9222标志运行)
  • 导航选项卡到测试页
  • 试图尽快呈现300帧动画的选项卡中的评估代码。
  • 返回执行时间

下面是我代码中的一个片段:

代码语言:javascript
复制
//connect to a tab (you can find <tab-debug-id> on http://localhost:9222/json page)
var ws = new WebSocket("ws://localhost:9222/devtools/page/<tab-debug-id>");

ws.onerror = function() {
  //handle error
};

ws.onopen = function()
{
    //when connection is opened hard reload the page before we start
    ws.send(JSON.stringify({
        id: 1,
        method: "Page.reload",
        params: {
            ignoreCache: true
        }
    }));
};

ws.onmessage = function (evt)
{
    var data = JSON.parse(evt.data);

    if(data.id === 1) {
        //reload was successful - inject the test script
        setTimeout(function(){
           ws.send(JSON.stringify({
              id: 2,
              method: "Runtime.evaluate",
              params: {
                expression: '(' + injectedCode.toString() + '());'
              }
           }));
        }, 1000);
    } else if(data.id === 2) {
        //animation has finished - extract the result
        var result = data.result.result.value;
    }
};
票数 2
EN

Stack Overflow用户

发布于 2013-10-01 22:07:21

几个月前,我编写了一个小脚本,专门测量requestAnimationFrame的FPS和消耗量。

我不确定它能百分之百地帮助你,但是它能给你一个好的指针。

使用非常简单:

  • 在循环前的代码中的某个位置初始化米,在其中指定要用作米的div元素。
  • 确保您获取了requestAnimationFrame提供的参数,因为这将显示花费了多少时间(如果不是,它将返回到使用日期/时间方法)。
  • 使用此参数对其方法执行简单调用。

绿色表示您正在最佳FPS中运行(大多数情况下为60)。黄色意味着循环消耗超过了大约16.7ms,并且速度下降到了大约一半。橙色意味着你使用的预算是预算的两倍多等等。

该计量器使用加权FPS给您一个更准确的测量。

示例

代码语言:javascript
复制
var meter = new animMeter('divElementId');

function animate(timeArg) {

    /// funky stuff here

    meter.update(timeArg);

    requestAnimationFrame(animate);
}

在这里可以找到这方面的演示。

你会发现电表本身的代码在几乎底部预最小化。请随意复制和粘贴。它有麻省理工学院的执照。

和往常一样,在使用这样的仪表时:他们自己会消耗几毫秒来更新图形,从而引入一个很小的误差范围。

另一件要注意的是,rAF将始终运行,试图达到60 FPS,所以米永远不能测量更高的帧速率超过这一点。

如果您需要测量更高的帧率,您可以调用没有参数的update方法,使用setTimeout代替rAF,它将使用日期/时间来衡量性能--稍微不准确,但您可以获得更高的FPS数(即任意帧,因为监视器不能显示比任何情况下都同步的帧更多的帧。通常是60 fps)。

票数 2
EN

Stack Overflow用户

发布于 2013-10-01 19:48:48

您可以使用Date.now()来减少在创建对象上浪费的时间,它至少可以提高一些精度。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19120830

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档