Cómo medir el rendimiento de los gráficos del navegador

Ilmari Heikkinen

Comparación de gráficos del navegador en pocas palabras: dibuja tanto como puedas manteniendo una velocidad de fotogramas fluida. Una vez que disminuya la velocidad de fotogramas, sabrás cuánto puedes dibujar por fotograma. Fin de la publicación ¿No? Bien, explicaré un poco más.

¡Momento de ejemplo! A continuación, se muestra un pequeño fragmento de código con una función tick de comparativas. La función tick llama a una función draw con una carga de dibujo creciente hasta que el dibujo tarda constantemente más de 33 ms.

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);

Consulta el ejemplo en vivo en jsFiddle.

Puedes ver que la comparativa sigue dibujando cada vez más hasta que llega al punto en el que se ralentiza. Esta es una manera agradable y simple de determinar cuánto puedes dibujar a una velocidad de fotogramas fluida. También puedes agregar tu propia función de dibujo al ejemplo y hacer algunas comparativas personalizadas.

Advertencias y dificultades comunes cuando se comparan los gráficos de los navegadores

Entonces, si el ejemplo anterior es una buena manera de hacerlo, ¿cuáles son las no tan buenas? Las maneras que te llevan a comparar elementos no relacionados o que te proporcionan métricas de rendimiento extrañas que no parecen estar relacionadas con la velocidad de ejecución de tu app. Me alegro de que hayas preguntado. Estas son las dos más comunes que he visto en la Web.

Mide el FPS máximo: dibuja un poco cada fotograma y mide los FPS. No funciona bien para medir el rendimiento de los gráficos en Chrome porque la implementación de gráficos subyacente se sincroniza con la frecuencia de actualización de la pantalla (por lo que obtienes un máximo de 60 actualizaciones de pantalla por segundo). Medir la velocidad de las llamadas de dibujo tampoco será muy útil, ya que el sistema de dibujo de Chrome coloca tus comandos de dibujo en un búfer de comandos que se ejecuta en la siguiente actualización de pantalla.

Otra mala idea es usar setTimeout para medir el rendimiento de los gráficos. El intervalo de setTimeout está limitado a 4 ms en navegadores, por lo que lo máximo que puedes obtener es 250 FPS. Históricamente, los navegadores tenían intervalos mínimos diferentes, por lo que es posible que hayas tenido una comparativa de dibujo trivial muy rota que mostraba al navegador A ejecutándose a 250 FPS (intervalo de 4 ms) y el navegador B a 100 FPS (intervalo de 10 ms como mínimo). Está claro que A es más rápido. ¡No! Podría suceder que B ejecutó el código de dibujo más rápido que A, por ejemplo, A tardó 3 ms y B tardó 1 ms. Esto no afecta los FPS, ya que el tiempo de dibujo es inferior al intervalo mínimo de setTimeout. Si el navegador se procesa de forma asíncrona, no hay nada mejor que tú. No uses setTimeout a menos que sepas lo que estás haciendo.

Cómo hacerlo, entonces

Una mejor manera de obtener comparativas es usar una carga de dibujo realista y multiplicarla hasta que la velocidad de fotogramas comience a disminuir. Por ejemplo, si escribes un juego de arriba abajo con un terreno de mapa de mosaicos, intenta dibujarlo en cada fotograma y ve si se ejecuta a 60 FPS. De ser así, aumenta la carga (dibuja el mapa de mosaicos dos veces en cada fotograma, con un valor claro en el medio). Continúa aumentando hasta que el FPS baje a un nuevo nivel estable. Ahora sabes cuántas capas del mapa de mosaicos puedes dibujar por fotograma.

Las diferentes aplicaciones gráficas tienen distintas necesidades, por lo que debes escribir tus comparativas teniendo eso en mente. Mide las funciones de gráficos que usas en tu app. Cuando encuentres una situación lenta, intenta reducirlo al fragmento de código más pequeño que lo reproduzca (y, si debería ser más rápido, envía un informe de errores en new.crbug.com).

Para ver cómo escribir código de gráficos web de alto rendimiento, consulta la charla Google I/O 2012 de Nat Duca y Tom Wiltzius del equipo de GPU de Chrome.