🤤

Reactのパフォーマンスカイゼン方法

2023/01/08に公開

この記事の目的

Reactにおけるパフォーマンスチューニングの基礎をあらためて振り返る

この記事で得られること

  • Reactのパフォーマンス戦略にについてざっくりと知れる
  • メモ化についてざっくりと知れる
  • キャッシュのメリットとTanstack Queryの概要についてめちゃざっくりと知れる

そもそもなぜパフォーマンスが大事なのか

個人的には以下の2点がパフォーマンス向上の意義だと思います。

  • UXの向上

    こちらは言わずもがなかと思います。こちらの記事によるとページ表示2秒でユーザーはイライラし始めるそうです。

  • SEOの向上

    2020年以降に、Googleが「Core Web Vitals」を検索ランキングの指標にしていくと発表し、パフォーマンス改善が注目を浴びるようになりました。

上記2点をまとめると、より多くのユーザにより良い価値を提供するために、パフォーマンス改善が必要だと考えられます。
その上で、今回はパフォーマンス改善方法のうち「メモ化」「キャッシュ戦略」の2点についてざっくりメモ書き程度にのこしてみます。

メモ化

メモ化とは

親コンポーネントのレンダリングに伴う、子コンポーネントの不要なレンダリングを排除するための処理です。

メモ化の仕組み

メモ化は、該当コンポーネントに渡されるPropsが変化したときのみ再レンダリングが走る仕組みとなっており、特定の条件満たされるまで、前の値をメモリ上にキャッシュすることができます。
こうすることで、該当コンポーネントと無関係の理由で再レンダリングが走った際、該当コンポーネントの再レンダリングをスキップすることができます。

どのような処理をメモ化すべきか

  • レンダリングコストが高いコンポーネント
  • 頻繁に再レンダリングされるコンポーネント内の子コンポーネント

React.memo

コンポーネントをメモ化する際に使用する高階関数。
React.memo は Props の等価性(値が等価であること)をチェックして再レンダリングの判断をし、コンポーネントのPropsの値が変更されるまで、前の値をメモリ上にキャッシュすることができます。

const MyComponent = React.memo(function MyComponent(props) {
  /* render using props */
});

useCallback

関数をメモ化する際に使用するHooks。
useCallback は、依存配列のいずれかが変更された場合にのみ変更されます。

const memoizedCallback = useCallback(
  () => {
    doSomething(a, b);
  },
  [a, b],
);

キャッシュ戦略

キャシュとは

キャッシュとは、データを一時的に保存しておくことを意味します。
これは、同じデータを繰り返し取得する必要がある場合、より速くデータを取得できるようにするために使用されます。
たとえば、あるWebサイトを閲覧するとき、Webブラウザはそのサイトのコンテンツを取得するためにサーバーにリクエストを送信し、そのサイトのコンテンツがキャッシュに保存されている場合、ブラウザはそのコンテンツをすぐに表示できます。

キャッシュ活用のメリット

  • UXの向上

    一度読み込んだWebサイトのデータを一時的に保存しておくことで、2回目以降はそのデータを再利用すれば重複するデータを取得せずに済み、読み込み時間が短縮されます。結果として、ユーザ体験向上が可能になります。

  • サーバ負荷の低減

    Fetch処理によるサーバーアクセス回数を減らすことで、サーバーの負荷を軽減することができます。

Reactにおけるキャッシュ戦略

TanStack Query (React Query)

Reactには、TanStack Query (元React Query)SWR様々なキャッシュ管理ライブラリがあります。
今回はその中の一つである、TanStack Queryについて、ごく簡単に紹介します。
TanStack Query とはサーバデータの非同期な状態をキャッシュ管理するためのdata fetchingライブラリです。
コンテンツの取得系、更新が可能です。

メリットとしては以下の通り

  • Fetch回数の削減

    「stileTime」というオプションを設定することで、データのフェッチ間隔を自由に設定することができます。

    静的なデータをAPIで取ってくる場合は、staleTimeの間隔を長く設定することで、無駄なFetchを削減することができ、パフォーマンス向上が見込めます。

  • コードの可読性向上

    下記の3つをよしなに、実装してくれるため、その分のコード量を削減することができます。

    • データフェッチング
    • fetch状況と結果の取得(loading, errorなど)
    • 取得データのグローバル化

また、Reactのグローバルな状態管理用HooksのuseContextでは、Contextコンポーネントのstateが更新された場合、同じContextコンポーネントで管理している、他のstateも再レンダリングが走ってしまいます。
なので、高パフォーマンスを実現するためにはContextのプロバイダーを複数作成しなければならないのですが、TanStack Queryではその心配はありません。

TanStack Queryの詳しいメリットについては以下が参考になります。
https://zenn.dev/mitsuruokura/articles/7372ae1be233c4

最後に

今回は、Reactにおけるパフォーマンス向上方法についてざっくり書いてみました。
他にもサーバサイドレンダリングやバンドルサイズの減少など、パフォーマンス向上方法はありますが、長くなるのでここまでにします(よく分かってないだけ)。

参考

https://ja.reactjs.org/docs/react-api.html
https://reactjs.org/docs/hooks-reference.html#usecallback
https://zenn.dev/koki_tech/articles/4d7aeaa9908040#実際にどれくらいメモ化で早くなるのか?

Discussion