web-dev-qa-db-ja.com

複数のrequestAnimationFrameパフォーマンス

複数のアニメーションを実行している場合、複数のrequestAnimationFrameコールバックを追加してもパフォーマンス上問題ありませんか? F.ex:

function anim1() {
    // animate element 1
}

function anim2() {
    // animate element 2
}

function anim3() {
    // animate element 3
}

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

または、単一のコールバックを使用するよりも悪いことが証明されています:

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

舞台裏で何が起こっているのか本当にわからないので、質問します。複数回呼び出すときにrequestAnimationFrameはコールバックをキューに入れますか?

44
David Hellsing

requestAnimationFrame doスタックの呼び出しとして、1つのrequestAnimationFrame呼び出しのみを使用する必要があります。したがって、単一のコールバックバージョンの方がパフォーマンスが高くなります。

7
Erik Schierboom

誰かがこれをベンチマークしました。話しましょう...

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

私はパフォーマンスの比較を見ました(あなたもそうすべきです)。あなたは反対することを歓迎します。これらは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);
        }

このコードは、timestamp()への7つの呼び出しとtimestamp()への2つの呼び出しのベンチマークを実際に行っていると思います。 Chrome 46と47の違いを見てください。

  • Chrome 46:12k/秒(1回の呼び出し)vs12k/秒(3コール)
  • Chrome 47:270k/秒(1回の呼び出し)vs810k/秒(3コール)

これは非常に最適化されているため、違いはありません。これは、この時点でノイズを測定しているだけです。

私の要点は、これをアプリケーション用に手動で最適化する必要がないことです。

パフォーマンスが心配な場合は、Chrome 59(1.8m ops/sec)とChrome 71(506k ops/sec)の違いを見てください。

3
Michael Cole