Como avaliar o desempenho gráfico do navegador

Ilmari Heikkinen

Comparação de gráficos do navegador em poucas palavras: desenhe o máximo possível enquanto mantém uma taxa de quadros suave. Quando o frame rate diminuir, você vai saber quanto pode desenhar por frame. Fim da postagem. Não? Ok, vou explicar um pouco mais.

Exemplo de hora! Veja um pequeno snippet de código com uma função tick de comparação. A função tick chama uma função draw com uma carga de desenho crescente até que ele demore mais 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);

Veja o exemplo ativo no jsFiddle (link em inglês)

É possível observar como a comparação continua sendo renderizada cada vez mais até chegar ao ponto em que fica mais lenta. Essa é uma maneira boa e simples de descobrir o quanto você pode desenhar com um frame rate estável. Você também pode conectar sua própria função de desenho ao exemplo e fazer algumas comparações personalizadas. Eba!

Advertências e armadilhas comuns ao comparar elementos gráficos do navegador

Então, se o exemplo acima é a maneira boa de fazer isso, quais são as maneiras não tão bacanas? As maneiras que levam ao comparativo de mercado de coisas não relacionadas ou que fornecem métricas de desempenho estranhas que parecem não ter nada a ver com a velocidade de execução do seu app. Que bom que você perguntou. Estas são as duas ocorrências mais comuns na Web.

Medir a QPS máxima: desenhe um pouco a cada frame e meça a taxa de QPS. Ela não funciona bem para medir o desempenho gráfico no Chrome porque a implementação gráfica subjacente é sincronizada com a taxa de atualização da tela (ou seja, você recebe no máximo 60 atualizações de tela por segundo). Medir a velocidade da chamada de desenho não será muito útil, já que o sistema de desenho do Chrome coloca os comandos em um buffer de comando que é executado na próxima atualização da tela.

Usar setTimeout para medir o desempenho de gráficos é outra má ideia. O intervalo setTimeout é limitado a 4ms nos navegadores, então o máximo que você pode conseguir são 250 QPS. Historicamente, os navegadores tinham diferentes intervalos mínimos, então você pode ter tido uma comparação de desenho muito corrompida que mostrou o navegador A em execução a 250 QPS (intervalo de 4 ms) e o navegador B em execução a 100 QPS (intervalo mínimo de 10 ms). Claramente A é mais rápido! Não! Pode ser que B tenha executado o código de desenho mais rápido do que A, digamos que A levou 3 ms e B de 1 ms. Não afeta o QPS, porque o tempo de exibição é menor que o intervalo mínimo setTimeout. E se o navegador for renderizado de maneira assíncrona, todas as apostas serão canceladas. Não use setTimeout a menos que você saiba o que está fazendo.

Como fazer isso

Uma maneira melhor de comparar é usar uma carga de desenho realista e multiplicá-la até que o frame rate comece a aumentar. Por exemplo, se você estiver escrevendo um jogo de cima para baixo com um terreno de bloco de blocos, tente desenhar o bloco de blocos a cada frame e verificar se ele é executado a 60 QPS. Em caso afirmativo, aumente a carga (desenhe o bloco de blocos duas vezes por frame, com um espaço claro no meio). Continue aumentando até que a taxa de QPS caia para um novo nível estável. Agora você sabe quantas camadas de bloco de blocos podem ser desenhados por frame.

Diferentes aplicativos gráficos têm necessidades diferentes, então você deve criar as comparações levando isso em consideração. Avalie os recursos gráficos que você usa no app. Quando encontrar um cenário lento, reduza-o para o menor trecho de código que possa ser reproduzido. Envie um relatório do bug em new.crbug.com se isso for mais rápido.

Para aprender a escrever código gráfico de alto desempenho para a Web, confira a palestra do Google I/O 2012 com Nat Duca e Tom Wiltzius, da equipe de GPU do Chrome.