我正在为JavaScript性能竞赛构建一个测试平台。其中一项任务要求参赛者优化负责处理画布动画的JavaScript代码。提交解决方案后,服务器使用PhantomJS运行它,并在20秒的动画后读取FPS的平均数量。问题是,我得到了3-4FPS的优化和未优化的代码。这使得无法判断代码是否得到了改进。
几个事实:
requestAnimationFrame,所以我不得不使用聚脂填充frameCounter.js
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);
}
}
})();我的问题是:如何以编程方式衡量画布动画的性能?
发布于 2013-10-18 07:59:20
由于幻影似乎无法在任何动画上产生超过3-4个FPS,所以我最终使用了“真正的”浏览器来完成这项任务。多亏了Chrome的远程调试协议,我才能实现它的自动化。
我制作了一个node.js应用程序,每次需要测试新代码时,执行以下步骤:
--remote-debugging-port=9222标志运行)下面是我代码中的一个片段:
//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;
}
};发布于 2013-10-01 22:07:21
几个月前,我编写了一个小脚本,专门测量requestAnimationFrame的FPS和消耗量。
我不确定它能百分之百地帮助你,但是它能给你一个好的指针。

使用非常简单:
绿色表示您正在最佳FPS中运行(大多数情况下为60)。黄色意味着循环消耗超过了大约16.7ms,并且速度下降到了大约一半。橙色意味着你使用的预算是预算的两倍多等等。
该计量器使用加权FPS给您一个更准确的测量。
示例
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)。
发布于 2013-10-01 19:48:48
您可以使用Date.now()来减少在创建对象上浪费的时间,它至少可以提高一些精度。
https://stackoverflow.com/questions/19120830
复制相似问题