web-dev-qa-db-ja.com

JavaScript OnScrollパフォーマンス比較

Update:非常に良い答えを含む同様の質問で、requestAnimationFrameとスクロールを便利な方法で使用する方法を示しています: scrollイベント:requestAnimationFrame VS requestIdleCallback VSパッシブイベントリスナー


では、スクロールによってトリガーされる高価なアクションをサイトに追加するとします。たとえば、jsfiddleで視差効果を使用しています。

今、私はそれをイベントに直接バインドしてはいけないことを読み続けています。時には、より良いことを意図したスニペットが続くこともあります。ほんのいくつかの例:

  1. JavaScriptハンドラーをスクロールイベントにアタッチ=悪い!
  2. 高性能のonScrollイベントを開発するには?
  3. より高速なスクロール効果を作成するには?
  4. 60FPS onscrollイベントリスナー

彼らが言うことは基本的にこれをしないでください:

  // Bad guy 1
  $(window).scroll( function() {
    animate(ex1);
  });

またはこれ

  // Bad guy 2
  window.addEventListener('scroll', onScroll, false);
  function onScroll() {
    animate(ex2);
  }

ただし、タイムアウト、間隔、requestAnimationFrameなどを使用します。次に例を示します。

  // Good guy
  $(window).scroll( function() {
   scrolling1 = true;
  });

  setInterval( function() {
    if (scrolling1) {
      scrolling1 = false;
      animate(ex3);
    }
  }, 50 );

それで、私は行って、上記のリンクで見つけたオプションを、次のようにすべてのアプローチにカウンターを追加することによってそれらを比較しようとするjsfiddleに追加しました:

  // Test
  $(window).scroll( function() {
    counter = counter + 1;
    // output result of counter
    animate(ex1);
  });

完全な jsfiddle を確認するか、古いブラウザでこれを使用することをお勧めします: Scrolltest (同じ、jsfiddleではありません)

結果:スムーズに機能するすべてのものは、ほぼ同じ数の計算です。途切れ途切れのエフェクトを使用できる場合は、いくつかのリソースを保護できます。そして、私が読んだすべてに対して、これは私にとって論理的に思えます!

最初の質問:何か不足しているのですか、これは有効なテストですか?無効な場合、どうすれば正しくテストできますか? 編集:明確にするために、上記の方法のいずれかがパフォーマンスをまったく節約するかどうかをテストしたいと思います。

2番目の質問:有効なのに、なぜ誰もがスクロールに不安を感じますか?流体アニメーションがサイト全体で5000の計算を必要とする場合、とにかくそれを変更する方法はありませんか?

(まあ、チェックを使用してオブジェクトがビューポートにあるかどうかを判断することもありますが、正直なところ、これらのチェックが防止されたコード自体ほど高価ではないかどうか、特に次のような5つの異なる変数が関係している場合はわかりませんoffset、windowHeight、scrolltTop、getBoundingClientRectおよびouterHeight ...)

13
user127091

したがって、@ SirPeopleはすでに最初の質問に正しく回答しています。これは、アニメーション関数が呼び出される頻度を確認するための優れたテストですが、さまざまなスニペットのパフォーマンスを比較するための悪いテストです。

これは、実行のパフォーマンスの記録です。

performance test

関数animateはまったく高価ではありません。パフォーマンスの記録(次の写真)を撮りました。これは、私が見た1回の反復(ポイント1〜5)で0.64ミリ秒から1.29ミリ秒かかることを示しています。また、関数が完了すると、ページのコンテンツがほとんどないため、再描画に時間がかかりません(ポイント6)。時間を見てみると、5つのアニメーション機能すべてと再描画が10ミリ秒未満で行われていることがわかります。これは、通常の状況では、60 fpsの滑らかなアニメーションが得られることを意味します(ポイント7)。

また、onscrollイベントリスナーを比較する場合は、それぞれを独自にテストして結果を比較する必要があります。リスナーの1つが実際にブロックしている場合、それはページ全体に影響を及ぼし、パフォーマンスデバッグがなければ、それがどれであるかがわかりません。

私は2つのjsfiddles window.scroll[〜#〜] raf [〜#〜] を作成しました。そして、驚いたことに、違いはないようです。

なぜこれが気になるのですか?

上記のjsfiddlesに示されているように、イベントハンドラーが大きくなりすぎると、entireページが遅れます。

今何ですか?

私自身はパフォーマンスの第一人者ではありませんが、

5
Sandro

私があなたの質問とあなたのすべての発言を正しく受け取ったかどうかは完全にはわかりませんが、私はあなたに答えを出そうとします:

  • 何か不足していますか、これは有効なテストですか?それが無効な場合、どうすれば正しくテストできますか?

関数が呼び出された回数を測定している場合、これは有効なテストです。これは、もちろん、ブラウザーに依存します。SO、GPUが拡張されているかどうか、およびすでに質問でコメントされている他のいくつかのベンチマークパラメーターに依存します。

測定が正しいと考えると、タイムアウトまたはrequestAnimationFramework couldを使用すると、基本的に デバウンスまたはスロットル の原則に従っているため、時間を節約できます。基本的に、関数を必要以上に要求したり呼び出したりしたくない。タイマーの場合、キューに入れる関数呼び出しは少なくなります。 requestAnimationFrame の場合は、再描画する前に呼び出しをキューに入れ、それらを順番に実行するためです。タイムアウトでは、非常に重い場合、計算が重複する可能性があります。

私は requestAnimationFrameを使用する理由 でより良い答えを見つけました。これは、Shear、ちらつき、フレームスキップなどのブラウザーのアニメーションに関する主な問題を説明しています。また、優れたデモも含まれています。

あなたのテスト方法は正しいと思います。また、正しく解釈する必要があります。ハードウェアとエンジンが原因で、呼び出しがほぼ同じ数になる可能性がありますが、前述のように、デバウンスとスロットルはパフォーマンスを緩和します。

Twitterからのウィンドウスクロールにハンドラーをアタッチしないことをサポートするもう1つの記事 。 (免責事項:この記事は2011年のものであり、ブラウザーはスクロールの最適化をさまざまな方法で処理しています)。

  • なぜ誰もがオンスクロールに神経質になるのですか?流体アニメーションがサイト全体で5000の計算を必要とする場合、とにかくそれを変更する方法はありませんか?

パフォーマンスヒットに緊張はないと思いますが、スクロールの呼び出しが原因で発生する可能性がある上記のアニメーションの問題、またはタイマーとの同期が取れていない場合でも、ユーザーエクスペリエンスは最悪になります 'パフォーマンスの問題。人々は、スクロールの呼び出しを保存することをお勧めします。なぜなら、人間の視覚的耐久性は、非常に高いフレームレートを必要としないため、より頻繁に画像を表示しようとしても役に立たないからです。より複雑な計算または重いアニメーションの場合、確認したように、ブラウザーはすでに最適化に取り組んでいます ブラウザーがこれを最適化していた 2、3、または6年前に公開した記事が作成されたのと比較して。

7
SirPeople