Mesurer les performances graphiques du navigateur

Ilmari Heikkinen

En résumé, le benchmark des graphismes du navigateur consiste à dessiner autant que possible tout en conservant une fréquence d'images fluide. Une fois que votre fréquence d'images baisse, vous savez combien vous pouvez dessiner par frame. Fin du post. Personne ? OK, je vais vous expliquer plus en détail.

Exemple de temps ! Voici un petit extrait de code avec une fonction tick d'analyse comparative. La fonction tick appelle une fonction draw avec une charge de dessin croissante jusqu'à ce que le dessin prenne régulièrement plus 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);

​ Consultez l'exemple en direct sur jsFiddle.

Vous pouvez voir comment le benchmark continue de dessiner de plus en plus jusqu'à ce qu'il ralentisse. C'est un moyen simple et pratique de déterminer la quantité de dessins que vous pouvez réaliser à une fréquence de frames fluide. Vous pouvez également ajouter votre propre fonction de dessin à l'exemple et effectuer des benchmarks personnalisés.

Mises en garde et pièges courants lors du benchmarking des graphismes du navigateur

Si l'exemple ci-dessus est la bonne façon de procéder, quelles sont les autres méthodes possibles ? Les méthodes qui vous permettent de comparer des éléments sans rapport ou qui vous fournissent des métriques de performances étranges qui ne semblent pas avoir quoi que ce soit à voir avec la vitesse d'exécution de votre application. Je suis ravi que vous me posiez cette question. Voici les deux plus courantes que j'ai vues sur le Web.

Mesure du FPS maximal: dessinez un peu à chaque frame et mesurez les FPS. Il n'est pas adapté à la mesure des performances graphiques dans Chrome, car l'implémentation graphique sous-jacente est synchronisée avec la fréquence d'actualisation de l'écran (vous obtenez donc un maximum de 60 mises à jour d'écran par seconde). Mesurer la vitesse des appels de dessin ne sera pas très utile non plus, car le système de dessin de Chrome place vos commandes de dessin dans un tampon de commandes qui est exécuté lors du prochain rafraîchissement de l'écran.

Utiliser setTimeout pour mesurer les performances graphiques est une autre mauvaise idée. L'intervalle setTimeout est limité à 4 ms dans les navigateurs. Vous ne pouvez donc pas dépasser 250 FPS. Historiquement, les navigateurs avaient des intervalles minimaux différents. Vous avez donc peut-être eu un benchmark de dessin trivial très cassé qui montrait que le navigateur A fonctionnait à 250 FPS (intervalle minimal de 4 ms) et le navigateur B à 100 FPS (intervalle minimal de 10 ms). Il est clair que la solution A est plus rapide. Non ! Il est possible que B ait exécuté le code de dessin plus rapidement qu'A, par exemple si A a pris 3 ms et B 1 ms. Cela n'a aucune incidence sur les FPS, car la durée de dessin est inférieure à l'intervalle minimal de setTimeout. Et si le navigateur effectue le rendu de manière asynchrone, tout est possible. N'utilisez pas setTimeout, sauf si vous savez ce que vous faites.

Comment procéder ?

Une meilleure méthode consiste à utiliser une charge de dessin réaliste et à la multiplier jusqu'à ce que la fréquence d'images commence à ralentir. Par exemple, si vous écrivez un jeu à vue aérienne avec un terrain de carte de tuiles, essayez de dessiner la carte de tuiles à chaque frame et de voir si elle s'exécute à 60 FPS. Si oui, augmentez la charge (dessinez le mappage de tuiles deux fois par frame, avec un effacement entre les deux). Continuez d'augmenter la valeur jusqu'à ce que les FPS atteignent un nouveau niveau stable. Vous savez maintenant combien de calques de carte de tuiles vous pouvez dessiner par frame.

Les applications graphiques n'ont pas toutes les mêmes besoins. Tenez-en compte lorsque vous rédigez vos benchmarks. Mesurez les fonctionnalités graphiques que vous utilisez dans votre application. Lorsque vous trouvez un scénario lent, essayez de le réduire au plus petit morceau de code qui le reproduit (et envoyez un rapport de bug sur new.crbug.com s'il devrait être plus rapide).

Pour savoir comment écrire du code graphique Web hautes performances, regardez la conférence Google I/O 2012 de Nat Duca et Tom Wiltzius de l'équipe GPU de Chrome.