React Hookレンダリングの最適化


クロムを使用した拡張ツール「React Developer Tools」



コンポーネントレンダリング項目を確認すると、React Developer Toolsのコンポーネントがハイライト表示され、レンダリング領域が表示されます.

応答のパフォーマンス最適化とは?


Reactは、まず構成部品をレンダリングし、その後、以前のレンダリングの結果と比較してDOM更新を決定します.レンダリング結果が以前と異なる場合、ReactはDOMを更新します.
Re-Renteringの場合、3つのケースがあります.
  • 受信props値更新時は
  • 州が
  • に変更されました
    親コンポーネント
  • を再レンダリングする場合、
  • 複数のステータスとpropsで1つだけ変更し、親構成部品の再表示によって不要なサブ構成部品が再表示されると、パフォーマンスが低下する可能性があります.
    Reactにおいて、性能最適化とは、Re−Renteringを最小化することを意味する.
  • Memoizationについて🔻 計算された計算結果を覚えてから同じ計算をさせると、再計算されていない記憶されているデータのメソッドが返されます.
  • useCallback()を使用したパフォーマンスの最適化

    import React, { useCallback } from "react";
    
    useCallback(() => {}, []);
    
    //첫번째 인자 = 콜백함수
    //두번쨰 인자 = 의존성배열 

    React公式文書


    コメントは完了したコールバックを返します.行内コールバックとその依存値の配列を渡してください.useCallbackはコールバック注釈の解析済みバージョンを返します.コールバックの依存性が変化した場合にのみ、コールバックのバージョンが変更されます.不要なレンダリングを回避するために(たとえばshouldComponentUpdateを使用する)、コールバックを参照同一性に依存する最適化されたサブエレメントに渡すと便利です.
    参照整合性に依存する最適化されたサブエレメントにコールバックを渡す場合に便利です.すなわち、コールバック関数をpropsとして最適化されたサブエレメントに渡す場合に便利です.
  • サンプルコード
    
    const TodoTemplate = () => {
      const [localTodo, setLocalTodo] = useLocalStorage<ITodo[]>('todoList', []);
    
      const deleteCompletedTodo = useCallback((): void => {
    
      const todoUpDate = useCallback((todo: ITodo): void => {
        setLocalTodo((prevState) => [...prevState, todo]);
      }, []);
    
      return (
        <>
          <TodoCreate todoUpDate={todoUpDate} />
          <TodoList localTodo={localTodo} setLocalTodo={setLocalTodo} />
        </>
      );
    };
    TodoTemplateは、TodoUpdateという関数をサブアセンブリTodoCreateに渡し、TodoListは、代替のLocalTodoを使用して画面を描画する.「ユーザコールバック」を使用しない場合、「ToDoList」でlocalTodo値を変更するたびに、まったく関係のないtoDoUpdateが再生成されます.これを防止するために,依存配列に空の配列を追加し,以前に関数を1回しか作成しなかった.
  • userMemo()を使用したパフォーマンスの最適化

    import React, { useMemo } from "react";
    
    const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);

    React公式文書


    作成関数とその依存値の配列を渡します.ユーザーMemoは、依存性が変化した場合にのみ、コメントが解析された値を再計算します.この最適化により、すべてのレンダリングでの高コスト計算が回避されます.userMemoに渡される関数は、レンダリング中に実行されることを覚えておいてください.この関数では、通常レンダリング中にしないことをしないでください.たとえば、サイドエフェクト(side effect)は、userMemoではなくuserEffectで実行されます.タイリングされていない場合は、レンダーするたびに新しい値が計算されます.

    userMemoは値を返します!


    関数があり、その関数が値を返している場合に、その値の演算を最適化したい場合は、userMemoを使用してDABが値が変化したときにのみその値の演算を実行し、その関数を使用して値のように演算を最適化することを指定します.
  • サンプルコード
    export function Movie({ title, releaseDate }) {
      return (
        <div>
          <div>Movie title: {title}</div>
          <div>Release date: {releaseDate}</div>
        </div>
      );
    }
    
    export default React.memo(Movie);
    
    //사용시
    
    <Movie
      movieTitle="Heat"
      releaseDate="December 15, 1995"
    />
    
    // 다시 렌더링 할 때 React는 MemoizedMovie 함수를 호출하지 않는다.(props로 넘겨주는 값이 변하지 않았을 경우!)
    // 리렌더링을 막는다.
    <Movie
      movieTitle="Heat"
      releaseDate="December 15, 1995"
    />
    を再使用してキャラクタリゼーションした結果を注記することにより、Reactで再レンダリングを行う場合、仮想DOMでの変化は確認されず、パフォーマンス上のメリットが得られる.
  • props同等比較カスタマイズ

    React.memo()道具または道具の対象を比較する場合  浅い(浅い)  と呼びます.
    比較方法を変更する場合は  React.memo()  2番目のパラメータで比較関数を作成して渡します.
    React.memo(Component, [areEqual(prevProps, nextProps)]);
    areEqual(prevProps, nextProps)  関数は  prevPropsおよび  nextPropsが同じなら  は、trueを返します.
    上記のサンプルコードのMovieのporpsが同じかどうかを手動で比較します.
    function moviePropsAreEqual(prevMovie, nextMovie) {
      return (
        prevMovie.title === nextMovie.title &&
        prevMovie.releaseDate === nextMovie.releaseDate
      );
    }
    
    const MemoizedMovie = React.memo(Movie, moviePropsAreEqual);
    moviePropsAreEqual()関数の前  propsおよび現在  propsが同じなら  trueを返し、以前の値を使用しないで再レンダリングします.

    useCallback()とuseMemo()の共通点


    depsが変化した場合、コメントが返されます.

    useCallback()とuseMemo()の違い


    useMemoの目的は関数の値を返すことであり,関数の演算量が大きい場合には以前の結果値を再利用することである;useCallbackの目的は関数を返すことであり,関数の再生を防止することである.