React 関数コンポーネントのパフォーマンス最適化のアイデアの詳細な説明

React 関数コンポーネントのパフォーマンス最適化のアイデアの詳細な説明

最適化のアイデア

最適化には主に 2 つの方向があります。

  1. 再レンダリングの回数を減らします。 React で最も重い (最も時間のかかる) 部分は、調整 (簡単に言えば diff) です。レンダリングしないと、調整は行われません。
  2. 計算量を減らします。主な目的は、繰り返し計算を減らすことです。関数コンポーネントの場合、各レンダリングは最初から関数呼び出しを実行します。

クラスコンポーネントを使用する場合、使用されるReact最適化APIは主としてshouldComponentUpdateとPureComponentです。

では、機能コンポーネントのパフォーマンスを最適化するにはどうすればよいでしょうか?最適化には主に以下の方法が使用されます。

  • リアクトメモ
  • コールバックの使用
  • メモを使う

リアクトメモ

例を見てみましょう:

サブタイトルを変更するためのボタンを親コンポーネントに配置し、子サブコンポーネントを導入します。

ご覧のとおり、サブコンポーネントが初めて登場すると、console.log('I am a subcomponent') が出力されます。

クリックしてサブタイトルを変更すると、子コンポーネントも印刷され、不要なレンダリング時間が繰り返されます。

//親コンポーネント import {useState} from 'react'

「./Child」からChildをインポートします。
定数インデックス = ()=>{
    const [subTitle, setSubTitle] = useState('私はサブタイトルです')
    const サブタイトルを更新 = ()=>{
      setSubTitle('サブタイトルを変更')
    }
    戻る (
      <div>
        <div>機能コンポーネントのパフォーマンス最適化</div>
        <div>{サブタイトル}</div>
        <button onClick={updateSubTitle}>サブタイトルを変更</button>
        <子供/>
      </div>
    );
  }
  
  デフォルトのインデックスをエクスポートします。


//子コンポーネント Child.js
定数子 = ()=>{
    console.log('私は子コンポーネントです')
    戻る (
        <div>私は子コンポーネントです</div>
    )
}
デフォルトの子をエクスポート

最適化し、React.memoを使用してサブコンポーネントをラップします。

「react」からReactをインポートします。

定数子 = ()=>{
    console.log('私は子コンポーネントです')
    戻る (
        <div>私は子コンポーネントです</div>
    )
}
デフォルトのReact.memo(Child)をエクスポートする

もう一度観察すると、子サブコンポーネントが繰り返しレンダリングされていないことがわかります。

コールバックの使用

ここで再度変更し、Child サブコンポーネントに onclick イベントを追加して、サブタイトルの変更ボタンをクリックすると、Child サブコンポーネントが再レンダリングされます。これは主に、handlerClick 関数がサブタイトルを変更するときに変更を再レンダリングし、サブコンポーネントが再レンダリングされるためです。

// 親コンポーネント const Index = ()=>{
    const [subTitle, setSubTitle] = useState('私はサブタイトルです')
    const サブタイトルを更新 = ()=>{
      setSubTitle('サブタイトルを変更')
    }
    const ハンドラクリック = ()=>{
      console.log('サブコンポーネントのクリック')
    }
    戻る (
      <div>
        <div>機能コンポーネントのパフォーマンス最適化</div>
        <div>{サブタイトル}</div>
        <button onClick={updateSubTitle}>サブタイトルを変更</button>
        <子の onClick={handlerClick}/>
      </div>
    );
  }

//子サブコンポーネント const Child = (props)=>{
    console.log('私は子コンポーネントです')
    戻る (
        <div>
            <div>私は子コンポーネントです</div>
            <button onClick={props.onClick}>サブコンポーネントボタン</button>
        </div>
    )
}
デフォルトのReact.memo(Child)をエクスポートする

最適化するには、useCallbackを使用して子コンポーネントのhandlerClick関数をラップし、updateSubTitleをもう一度クリックしてサブタイトルを変更し、子サブコンポーネントが再レンダリングされないことを確認します。

// 親コンポーネント const Index = ()=>{
    const [subTitle, setSubTitle] = useState('私はサブタイトルです')
    const サブタイトルを更新 = ()=>{
      setSubTitle('サブタイトルを変更')
    }
    定数ハンドラクリック = useCallback(()=>{
      console.log('サブコンポーネントのクリック')
    },[])

    戻る (
      <div>
        <div>機能コンポーネントのパフォーマンス最適化</div>
        <div>{サブタイトル}</div>
        <button onClick={updateSubTitle}>サブタイトルを変更</button>
        <子の onClick={handlerClick}/>
      </div>
    );
  }
  
  デフォルトのインデックスをエクスポートします。

useCallbackの使い方は次のとおりです。

定数コールバック = () => {
  何かを実行します(a, b);
}

const memoizedCallback = useCallback(コールバック、[a, b])

関数と依存関係をパラメーターとして useCallback に渡すと、コールバック関数のメモ化されたバージョンが返されます。この memoizedCallback は、依存関係が変更された場合にのみ更新されます。

メモを使う

useMemoは計算結果をキャッシュするために使用されます

例を見てみましょう。前のものをベースに calcCount 計算関数を追加し、updateSubTitle をクリックして字幕を更新します。calcCount が再計算されることがわかります。つまり、レンダリングごとに繰り返し計算が発生します。計算量が多いと、パフォーマンスに大きな影響を与えます。

// 親コンポーネント const Index = ()=>{
    const [subTitle, setSubTitle] = useState('私はサブタイトルです')
    const サブタイトルを更新 = ()=>{
      setSubTitle('サブタイトルを変更')
    }
    定数ハンドラクリック = useCallback(()=>{
      console.log('サブコンポーネントのクリック')
    },[])

    定数calcCount = ()=>{
      
      合計カウントを 0 にする
      (i=0;i<10000;i++とします){
        合計数+=i
      }
      コンソールログ('合計カウント',合計カウント)
      合計数を返す
    }

    定数count = calcCount()

    戻る (
      <div>
        <div>機能コンポーネントのパフォーマンス最適化</div>
        <div>{サブタイトル}</div>
        <button onClick={updateSubTitle}>サブタイトルを変更</button>
        <div>カウント:{count}</div>
        <子の onClick={handlerClick}/>
      </div>
    );
  }

最適化し、useMemo を使用して計算結果をキャッシュします。もう一度 updateSubTitle ボタンをクリックすると、サブタイトルが変更されます。calcCount 関数が計算を繰り返さなくなったことがわかります。

 定数calcCount = ()=>{
      
      合計カウントを 0 にする
      (i=0;i<10000;i++とします){
        合計数+=i
      }
      コンソールログ('合計カウント',合計カウント)
      合計数を返す
    }

    定数count = useMemo(calcCount,[])

最後に、useMemo を盲目的に使用することはできないことに注意してください。特定のシナリオに応じて使用する必要があります。たとえば、データ計算の量が比較的大きい場合は、より適用できます。計算する価値のある通常の計算では、useMemo 自体もパフォーマンスを消費するため、無視できます。盲目的に使用すると逆効果になります。

参考文献

https://mp.weixin.qq.com/s/YGvmSrr-yhPUNHbwlLSFsA

http://www.ptbird.cn/react-hook-useMemo-purerender.html

React 関数コンポーネントのパフォーマンス最適化に関するこの記事はこれで終わりです。React パフォーマンス最適化に関するより関連性の高いコンテンツについては、123WORDPRESS.COM の過去の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • ReactコンポーネントライブラリにTypeScriptタイプヒントを追加する方法
  • Reactコンポーネントの種類と使用シナリオに関する深い理解
  • Reactの親コンポーネントを介して子コンポーネントにクラス名を渡す実装方法
  • React の機能コンポーネントとクラスコンポーネントの違いをご存知ですか?

<<:  MySql 5.7.20 のインストールとデータおよび my.ini ファイルの構成

>>:  NodeサイトのForever+nginx導入方法例

推薦する

Vueはタブルーティング切り替えコンポーネントのメソッド例を実装します

序文この記事では、vue に付属している vue-router.js ルーティングを使用してページン...

CSS3 における構造擬似クラスセレクターと擬似要素セレクターの使い方の詳細な説明

構造擬似クラスセレクタの紹介構造擬似クラスセレクターは、いくつかの特殊効果を処理するために使用されま...

HTML コード作成ガイド

共通コンベンションタグ自己終了タグ。閉じる必要はありません (例: img input br hr ...

js 属性オブジェクトの hasOwnProperty メソッドの使用

オブジェクトの hasOwnProperty() メソッドは、オブジェクトに特定の独自の (継承され...

HTML+CSS+JavaScript でガールフレンド版のスクラッチ カードを作成します (一度見ればすぐに覚えられます)

誰もがスクラッチ チケットで遊んだことがあると思います。子供の頃、ポケットにお金が入るとすぐに友達に...

JavaScriptとTypeScriptの関係

目次1. JavaScript とは何ですか? 2. JavaScript は何に使用されますか? ...

MySql 自動切り捨て例の詳細な説明

MySql 自動切り捨て例の詳細な説明友人が質問しました。プロジェクト内で挿入または更新ステートメン...

アイデアを使用して Springboot 初期化サーバーを構築する際の問題分析

問題の説明最近、Springbootプロジェクトを構築していたところ、会社のネットワークケーブルに接...

要素の高さを下から上へ、上から下へ制御する CSS メソッド

よくある質問から議論を始めましょう。CSS を使用して要素の高さを [ブラウザ コンテンツ ウィンド...

HTML タグ sup と sub の応用の紹介

HTML タグ: 上付き文字HTML では、<sup> タグは上付き文字のテキストを定義...

1つの記事でJavaScript DOM操作の基本を学ぶ

DOM の概念DOM: ドキュメント オブジェクト モデル: ドキュメント オブジェクト モデルは、...

Linux で crontab 出力リダイレクトが有効にならない問題の解決方法

質問LINUX では、定期的なタスクは通常、cron デーモン プロセス [ps -ef | gre...

MYSQL フルバックアップ、マスタースレーブレプリケーション、カスケードレプリケーション、および半同期の概要

MySQL フルバックアップ1. バイナリログを有効にし、データベースから分離して別々に保存する v...

フレックスレイアウトは、1行あたりの固定行数と適応レイアウトを実現します。

この記事では、1行あたりの固定行数+アダプティブレイアウトを実現するフレックスレイアウトを紹介し、皆...

CSSプロパティに基づいたボタンホバーボーダーと背景アニメーションのコレクション

ハートの属性不透明度: .999 は要素のスタッキングコンテキストを作成し、ボタン6と8のアニメーシ...