Reactjs - React での非常に高速な setState 呼び出しによるパフォーマンスの問題?

okwaves2024-01-25  11

簡単なドラッグ可能なコンポーネントを作成しました。私は反応スワイプ可能なライブラリを使用していますが、私の質問は、useState を繰り返し短期間で更新するイベントに関するものです。

onSwiping の console.log を使用すると、関数が 1 秒間に何度も呼び出されていることがわかります。これは、コンポーネントの位置を更新するために必要なものです。これは機能しますが、setSwipeX を頻繁に呼び出すとパフォーマンスに問題がありますか?

コンポーネント全体は、ドラッグされると非常に高速に再レンダリングされます。これで問題ありませんか、それともコンポーネント全体を再レンダリングせずに swipeX を更新するだけの方がよいでしょうか。また、これは可能ですか?

import React from "react";
import { useSwipeable } from "react-swipeable";

export default function App() {
  const [swipeX, setSwipeX] = React.useState(0);

  const swipeHandlers = useSwipeable({
    onSwiping: (e) => {
      console.log(e);
      setSwipeX(-e.deltaX);
    },
    trackMouse: true
  });

  return (
    <div
      className="App"
      {...swipeHandlers}
      style={{
        transform: `translateX(${swipeX}px)`
      }}
    >
      <h1>Stuff</h1>
    </div>
  );
}

https://codesandbox.io/s/relaxed-minsky-ni7n9?file=/src/App.js

パフォーマンスの問題を観察しましたか? React は状態の更新をバッチ処理することに注意してください (reactjs.org/docs/react-component.html#setstate を参照)。そのため、常に前の状態の値に依存できるわけではありません。

– ジョンシャープ

2020 年 9 月 3 日 10:44

実際にはそうではありませんが、これは非常に単純な例です。実際には、コンポーネントはさらに複雑になります。また、低速度の MacBook ではなく、高速な MacBook でのみテストしました。仕様のモバイル デバイス。

– エヴァンス

2020 年 9 月 3 日 11:03

react を使用するということは、すべてに React を使用する必要があるという意味ではありません。生の JavaScript 変数と関数を作成して、transform プロパティを処理し、他のすべてに React を使用できます。

– ナタナエル

2020 年 9 月 5 日 12:32

この中で React を使用する代わりに単純な JavaScript を使用できますか?のユースケースに対応し、デバウンス/スロットリングなどのテクニックを使用して複数回実行される関数を制御できます。

– ドリー

2020 年 9 月 5 日 12:37



------------------------

私はパフォーマンスに関しては専門家ではありませんが、数週間前にページ コンポーネントを下にスワイプできるコンポーネントを実装しました。あなたがやっていることと非常に似ていますが、垂直方向です。初めて useState を使用してこれを試みたとき、Pixel 3a では問題はありませんでした。しかし、Nexus 5x でテストしたところ、まったくスムーズではありませんでした。 userState ではなく useRef を使用するようにロジックを変更したところ、動作がはるかにスムーズになりました。このようなもの:

import React from "react";
import { useSwipeable } from "react-swipeable";

export default function App() {
  const ref = React.useRef(null);

  const swipeHandlers = useSwipeable({
    onSwiping: (e) => {
      console.log(e);
      ref.style.transform = `translateX(${-e.deltaX}px)`;
    },
    trackMouse: true
  });

  return (
    <div
      className="App"
      {...swipeHandlers}
      ref={ref}
    >
      <h1>Stuff</h1>
    </div>
  );
}

この方法では、DOM を直接変更します。繰り返しになりますが、数値でテストしたわけではありませんが、ローエンドのデバイスでは物理的に若干の違いが確認できました。



------------------------

上記の例での useState の使用は、マウスの動きを追跡するという目的の機能を実現するために必要です。

私の経験から、useState を繰り返し呼び出してもパフォーマンスの問題が発生しないことがわかりました。実際、useState は React を使用する主な利点の 1 つであり、繰り返し呼び出しを行う他の方法よりも優れたパフォーマンスを提供します。

一方、私の経験から言えば、および以下:

useEffect を繰り返し呼び出すと、パフォーマンスに重大な影響を与える可能性があります。

状態オブジェクトが大量の情報 (数 KB のデータ) を保持する複雑なデータ構造である場合、useState への繰り返し呼び出しはメモリ消費に影響を与える可能性があります。

上記の例では、useState を繰り返し呼び出します。 ただし、状態オブジェクトはシンプルで非常に小さい (メモリを数バイトしか消費しない 1 つの変数)。

また、上の例では、頻繁にリソースを消費する useEffect は使用されていません。

したがって、useState を繰り返し呼び出しても、上記のシナリオではパフォーマンスに影響はありません。

総合生活情報サイト - OKWAVES
総合生活情報サイト - OKWAVES
生活総合情報サイトokwaves(オールアバウト)。その道のプロ(専門家)が、日常生活をより豊かに快適にするノウハウから業界の最新動向、読み物コラムまで、多彩なコンテンツを発信。