如何衡量浏览器图形性能

Ilmari Heikkinen

对浏览器图形进行基准化分析的简述:在保持流畅的帧速率的前提下,尽可能多地绘制。一旦帧速率下降,您就会知道每帧可以绘制多少帧。帖子末尾。不是吗?好的,我会再解释一些。

示例时间!以下是包含基准化分析 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 毫秒。不会影响 FPS,因为绘制时间小于最短 setTimeout 间隔。如果浏览器异步呈现,就表示所有设置都已关闭。除非您知道自己正在做什么,否则请勿使用 setTimeout。

接下来该怎么做

更好的基准测试方法是使用真实的绘制负载并成倍提升,直到帧速率开始上升。例如,如果您正在编写一个采用图块地图地形的自上而下游戏,请尝试每一帧都绘制图块图,看看它是否以 60 FPS 运行。如果是,请增加负载(每帧绘制两次图块地图,中间要清晰)。继续提高 FPS 水平,直到 FPS 下降到新的稳定级别。现在,您已经了解了每帧可以绘制多少个图块图。

不同的图形应用有不同的需求,因此您在编写基准测试时应考虑到这一点。测量您在应用中使用的图形功能。当您发现某个运行缓慢的情形时,请尝试将其精简为可重现该情况的最小代码段(如果缩短测试速度,您可以在 new.crbug.com 上提交错误报告)。

要了解如何编写高性能网络图形代码,请观看来自 Chrome GPU 团队的 Nat Duca 和 Tom Wiltzius 的 Google I/O 2012 讲座。