浏览器图形基准测试的要点在于:在保持流畅的帧速率的同时,尽可能多地绘制。帧速率下降后,您就可以知道自己每帧可以绘制多少内容。帖子结束。没有?好的,我再详细说明一下。
示例时间!以下是一个包含基准测试 tick
函数的小代码段。tick
函数会调用 draw
函数,并逐渐增加绘制负载,直到绘制时间始终超过 33 毫秒。
var t, previousTime;
var drawLoad = 1;
var slowCount = 0;
var maxSlow = 10;
// Note, you might need to polyfill performance.now and requestAnimationFrame
t = previousTime = performance.now();
var tick = function() {
var maximumFrameTime = 1000/30; // 30 FPS
t = performance.now();
var elapsed = t - previousTime;
previousTime = t;
if (elapsed < maximumFrameTime || slowCount < maxSlow) {
if (elapsed < maximumFrameTime) {
drawLoad+=10;
} else {
slowCount++;
}
draw(drawLoad);
requestAnimationFrame(tick);
} else {
// found maximum sustainable load at 30 FPS
document.getElementById('res').innerHTML = ("could draw "+(drawLoad)+" in " +
maximumFrameTime + " ms");
}
};
requestAnimationFrame(tick);
请参阅 jsFiddle 上的实时示例
您可以看到基准测试如何不断绘制更多内容,直到达到速度变慢的程度。这是一种简单而实用的方法,可用于确定您可以在流畅的帧速率下绘制多少内容。您还可以将自己的绘制函数插入到示例中,并进行一些自定义基准测试,太棒了!
对浏览器图形进行基准测试时的常见注意事项和误区
那么,如果上述示例是正确的方法,那么哪些方法不太正确呢?导致您对不相关内容进行基准测试或提供似乎与应用运行速度毫无关系的奇怪性能指标的方法。很高兴您提出这个问题,下面是我在网络上看到的两个最常见的问题。
衡量最大 FPS:每帧绘制一点,然后衡量 FPS。它不适用于衡量 Chrome 上的图形性能,因为底层图形实现会与屏幕刷新率同步(因此每秒最多可获得 60 次屏幕更新)。测量绘制调用速度也不会很有帮助,因为 Chrome 的绘制系统会将绘制命令放入一个命令缓冲区,在下次屏幕刷新时执行。
使用 setTimeout 衡量图形性能也是一个错误的做法。在浏览器中,setTimeout 间隔时间的上限为 4 毫秒,因此您最多只能获得 250 FPS。过去,浏览器的最小间隔时间不同,因此您可能获得了一个非常不准确的琐碎绘制基准测试结果,其中显示浏览器 A 的运行速度为 250 FPS(最小间隔时间为 4 毫秒),浏览器 B 的运行速度为 100 FPS(最小间隔时间为 10 毫秒)。显然,A 的速度更快!不!很可能是因为 B 比 A 更快地运行了绘制代码,假设 A 花了 3 毫秒,B 花了 1 毫秒。由于绘制时间小于最小 setTimeout 间隔,因此不会影响 FPS。如果浏览器异步呈现,一切都无法预料。除非您知道自己在做什么,否则请勿使用 setTimeout。
后续如何操作
进行基准测试的更好方法是使用真实的绘制负载并对其进行乘法,直到帧速率开始下降。例如,如果您要编写一个采用平面图地形的从上向下游戏,请尝试每帧绘制平面图,并查看其是否以 60 FPS 运行。如果是,请增加负载(每帧绘制两次图块地图,中间进行一次清除)。继续增加,直到 FPS 下降到新的稳定水平。现在,您已经知道每帧可以绘制多少个图块地图层了。
不同的图形应用有不同的需求,因此您在编写基准测试时应考虑这一点。衡量您在应用中使用的图形功能。如果发现运行缓慢的情况,请尝试将其缩减为可重现该情况的最小代码段(如果可以更快地重现该情况,请前往 new.crbug.com 提交 bug 报告)。
如需了解如何编写高性能 Web 图形代码,请观看 Chrome GPU 团队的 Nat Duca 和 Tom Wiltzius 在 2012 年 Google I/O 大会上的演讲。