web-dev-qa-db-fra.com

Performances de requestAnimationFrame multiples

Si je fais plusieurs animations, est-ce correct pour les performances d'ajouter plusieurs rappels requestAnimationFrame? F.ex:

function anim1() {
    // animate element 1
}

function anim2() {
    // animate element 2
}

function anim3() {
    // animate element 3
}

requestAnimationFrame(anim1);
requestAnimationFrame(anim2);
requestAnimationFrame(anim3);

Ou est-il prouvé pire que d'utiliser un seul rappel:

(function anim() {
    requestAnimationFrame(anim);
    anim1();
    anim2();
    anim3();
}());

Je demande parce que je ne sais pas vraiment ce qui se passe dans les coulisses, est-ce que requestAnimationFrame fait la file d'attente des rappels lorsque vous l'appelez plusieurs fois?

44
David Hellsing

Vous ne devez utiliser qu'un seul appel requestAnimationFrame comme appels à la pile requestAnimationFrame do. La version à rappel unique est donc plus performante.

7
Erik Schierboom

Quelqu'un a évalué cela. Parlons...

https://jsperf.com/single-raf-draw-calls-vs-multiple-raf-draw-calls

J'ai regardé la comparaison des performances (vous devriez aussi). Vous êtes invités à être en désaccord. Ce sont des primitives de dessin sur un élément canvas.

        function timeStamp() {
          return window.performance && window.performance.now ? window.performance.now() : new Date().getTime();
        }

        function frame() {
            drawCircle();
            drawLines();
            drawRect();
        }

        function render() {
            if (timeStamp() >= (time || timeStamp())) {
                time = timeStamp() + delayDraw;
                frame();
            } 
            requestAnimationFrame(render);
        }

        function render1() {
            if (timeStamp() >= (time || timeStamp())) {
                time = timeStamp() + delayDraw;
                drawCircle();
            } 
            requestAnimationFrame(render1);
        }

        function render2() {
            if (timeStamp() >= (time || timeStamp())) {
                time = timeStamp() + delayDraw;
                drawRect();
            } 
            requestAnimationFrame(render2);
        }

        function render3() {
            if (timeStamp() >= (time || timeStamp())) {
                time = timeStamp() + delayDraw;
                drawLines();
            } 
            requestAnimationFrame(render3);
        }

Je pense que ce code compare vraiment 7 appels à timestamp () vs 2 appels à timestamp (). Regardez la différence entre Chrome 46 et 47.

  • Chrome 46: 12k /sec (un appel) vs 12k /sec (3 appels)
  • Chrome 47: 270k /sec (un appel) vs 810k /sec (3 appels)

Je pense que c'est tellement bien optimisé que cela ne fait aucune différence. Il s'agit simplement de mesurer le bruit à ce stade.

Ma conclusion est que cela n'a pas besoin d'être optimisé à la main pour mon application.

Si les performances vous inquiètent, regardez la différence entre Chrome 59 (1,8 million d'opérations/s) et Chrome 71 (506 000 opérations/s)).

3
Michael Cole