React コンポーネントのパフォーマンス最適化方法への回答
全体的なパフォーマンスを大幅に改善しないコードにパフォーマンスの最適化エネルギーを無駄にしないでください。パフォーマンスに重要な影響を与える部分を最適化するのに早すぎるということはありません。なぜなら、パフォーマンスに影響を与える最も重要な部分は、多くの場合、ソリューションのコアに関係し、アーキテクチャ全体を決定します。将来変更が必要になった場合、アーキテクチャはさらに複雑になるからです。
1. 単一の React コンポーネントのパフォーマンスの最適化
React は、ほとんどのコンポーネントを再レンダリングするために仮想 DOM を使用しますが、以前のレンダリング コンテンツをすべて破棄するわけではありません。 Virtual DOM の助けを借りて、React は DOM ツリーへの最小限の変更を計算できます。これが React レンダリングの秘訣です
ただし、Virtual DOM は各 DOM 操作の量を減らすことができます。最低限、仮想 DOM との比較はまだ複雑なプロセスです
もちろん、仮想 DOM の計算を開始する前にレンダリング結果が変わらないと判断できれば、仮想 DOM を計算して比較する必要はありません。 DOM を使用すると、速度が速くなります。
2. shouldComponentUpdateのデフォルト実装
レンダリング結果が変わらないと判断した場合、仮想DOMの計算を開始する前にコンポーネントのレンダリングを防ぐことができるため、パフォーマンスが向上します。当然、 shouldComponentUpdate( nextProp, nextState) を使用することを考えます
shouldComponentUpdate 関数は、「いつ再レンダリングする必要がないのか」を判断するために render 関数の前に呼び出されます。
は、更新を続行するかどうかを判断するためにブール値を返します。デフォルトでは true を返します。 false を返した場合、更新は中断されます
shouldComponentUpdate(nextProp,nextState){ return (nextProp.completed !== this.props.completed) || (nextProp.text !== this.props.text) }
ここで、nextProps は、このコンポーネントのレンダリング コンテンツに影響する唯一の props です。これら 2 つのプロパティが変更されていない限り、 shouldComponentUpdate は不要な更新を防ぐために false を返すことができます
ただし、型が基本型である限り、上記の比較は単なる「浅い比較」です。が同じである場合、「浅い比較」
も 2 つが同じであるとみなします:
次に、prop の型が複合オブジェクトの場合はどうなるでしょうか?
複雑なオブジェクトの場合、「浅い比較」メソッドは 2 つのプロパティが同じオブジェクトへの参照であるかどうかのみをチェックします。そうでない場合は、オブジェクトの内容がまったく同じであっても、それらは 2 つの異なるプロパティとみなされます。次に、「詳細比較」を使用します。ただし、オブジェクトの構造は予測できません。各フィールドに対して「詳細比較」を再帰的に実行すると、コードが複雑になるだけでなく、パフォーマンスの問題が発生する可能性があります。
したがって、前後のオブジェクトタイプのプロパティが同じであることを確認したい場合は、そのプロパティが同じJavaScriptオブジェクトを指していることを確認する必要があります:
<Foo styleProp = {{color: "red"}}>
上記の受信メソッドの使用を避けるにはメソッドでは、レンダリングによって {color: "red"} オブジェクトが再作成されるたびに行う必要があり、参照アドレスは毎回異なり、そのため styleProp も毎回異なります。
const footStyle = {color: "red"};//确保这个初始化只执行一次,不要放在render函数中 <Foo styleProp = {footStyle}>
「シングルトンモード」を使用して、渡された styleProp が同じオブジェクトを指していることを確認してください
それが関数の場合はどうなるでしょうか?
<Foo onToggle={() => onToggleTodo(item.id)}/>
ここで割り当てられる値は匿名関数であり、代入中に生成されるため、上記の関数転送モードの使用は避けてください。つまり、レンダリングされるたびに新しい関数が生成されることになります。ここが問題の箇所です。
渡される小道具がたくさんある場合はどうすればよいですか?
そうですね~~React-Redux を使用している場合は、 shouldComponentUpdate のデフォルト実装があります。
3. 複数の React コンポーネントのパフォーマンスの最適化
React コンポーネントがロード、更新、アンロードされると、コンポーネントの一連のライフサイクル関数が呼び出されます。ただし、これらのライフサイクル関数は特定の React コンポーネント関数用であり、アプリケーションでは多数の React コンポーネントが上から下まで結合されており、それらの間のレンダリング プロセスはより複雑になります。
同じコンポーネントのレンダリングプロセスでも、ロードフェーズ、更新フェーズ、アンロードフェーズの 3 つのプロセスを考慮する必要があります
ロードフェーズでは、コンポーネントはとにかく一度完全にレンダリングされ、そこからすべてのサブコンポーネントがレンダリングされる必要がありますReact コンポーネントを下向きに読み込む場合は、React コンポーネントの読み込みライフ サイクルを実行する必要があるため、最適化を行う必要はあまりありません。
コンポーネント更新プロセスでは、更新された仮想 DOM が構築され、以前の仮想 DOM と比較され、相違点が特定され、最小限の DOM 操作で更新されます
調整プロセス: つまり、React の更新中に Virtual DOM の違いを見つけるプロセスは、通常、N 個のノードを持つ 2 つのツリー構造を比較するアルゴリズムです。デフォルトの比較を直接使用し、ノード数が多すぎる場合、時間計算量は O(n*3) になります。必要な操作が多すぎるため、React がこのアルゴリズムを使用することは不可能です
React で実際に使用されるアルゴリズムの時間計算量は O(N) (時間計算量はアルゴリズムに必要な命令にすぎません)最良の場合と最悪の場合) 運用規模の推定)
React的Reconciliation算法并不复杂,首先检查两个树形的根节点的类型是否相同,根据相同或者不同有不同的处理方式:
节点类型不同的情况
如果树形节点的类型不相同,那就意味着改动很大,直接认为原来的那个树形结构已经没用,可以扔掉,需要从新构建DOM树,原有的树形上的React组件便会经历“卸载”的生命周期;
也就是说,对于Virtual DOM树这是一个“更新”过程,但是却可能引发这个树结构上某些组件的“装载”和“卸载”过程
如:
更新前
<p> <Todos /> </p>
我们想要更新成这样:
<span> <Todos /> </span>
>1. 那么在作比较的时候,一看根节点原来是p,新的是span,类型就不一样了,那么这个算法就废弃之前的p包括里面的所有子节点,从新构建一个span节点和子节点;
>2. 很明显因为根节点不同就将所有的子节点从新构建,这很浪费,但是为了避免O(N*3)的时间复杂度,React这能选择这种比较简单、快捷的方法;
>3. 所以,作为开发者,我们一定要避免上面的浪费的情景出现
节点类型相同的情况
如果两个节点类型相同时,对于DOM元素,React会保留节点对应的DOM元素,只对其节点的属性和内容做对比,然后只修改更新的部分;
节点类型相同时,对于React组件类型,React做得是根据新节点的props去更新节点的组件实例,引发组件的更新过程;
在处理完根节点对比后,React的算法会对根节点的每一个子节点重复一样的操作
多个相同子组件的情况
如果最初组件状态为:
<ul> <TodoItem text = "First" /> <TodoItem text = "Second" /> </ul>
更新后为:
<ul> <TodoItem text = "First" /> <TodoItem text = "Second" /> <TodoItem text = "Third" /> </ul>
那么React会创建一个新的TodoItem组件实例,而前两个则进行正常的更新过程但是,如果更新后为:
<ul> <TodoItem text = "Zero" /> <TodoItem text = "First" /> <TodoItem text = "Second" /> </ul>
(这将暴露一个问题)理想处理方式是,创建一个新的TodoItem组件实例放在第一位,后两个进入自然更新过程
但是要让react按照这种方式,就必须找两个子组件的不同之处,而现有计算两个序列差异的算法时间是O(N*2),显然则
不适合对性能要求很高的场景,所以React选择了一个看起来很傻的办法,即挨个比较每个子组件;
React首先认为把text为First的组件的text改为Zero,Second的改为First,最后创建一个text为Second的组件,这样便会破原有的两个组件完成一个更新过程,并创建一个text为Second的新组件
这显然是一个浪费,React也意到,并提供了方克服,不过需要开发人员提供一点帮助,这就是key
Key的使用
key属性可以明确的告诉React每个组件的唯一标识
如果最初组件状态为:
<ul> <TodoItem key={1} text = "First" /> <TodoItem key={2} text = "Second" /> </ul>
更新后为:
<ul> <TodoItem key={0} text = "Zero" /> <TodoItem key={1} text = "First" /> <TodoItem key={2} text = "Second" /> </ul>
因为有唯一标识key,React可以根据key值,知道现在的第二和第三个组件就是之前的第一和第二个,便用原来的props启动更新过程,这样shouldComponentUpdate就会发生作用,避免无谓的更新;
注意:因为作为组件的唯一标识,所以key必须唯一,且不可变
下面的代码是错误的例子:
<ul> todos.map((item,index) => { <TodoItem key={index} text={item.text} /> }) </ul>
使用数组下标作为key值,看起来唯一,但不稳定,因为随着todos数组值的不同,同样一个组件实例在不同的更新过程中数组的下标完全可能不同,把下标当做可以就会让React乱套,记住key不仅要唯一还要确保稳定不可变
需要注意:虽然key是一个prop,但是接受key的组件不能读取key的值,因为key和ref是React保留的两个特殊prop,并没有预期让组将直接访问。
相关推荐:
以上がReact コンポーネントのパフォーマンス最適化方法への回答の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック











残念ながら、WeChat は広く使用されているソーシャル ソフトウェアであり、何らかの理由で特定の連絡先を誤って削除してしまうことがよくあります。ユーザーがこの問題を解決できるように、この記事では、削除された連絡先を簡単な方法で取得する方法を紹介します。 1. WeChat の連絡先削除メカニズムを理解します。これにより、削除された連絡先を取得できるようになります。WeChat の連絡先削除メカニズムでは、連絡先がアドレス帳から削除されますが、完全には削除されません。 2. WeChat の組み込みの「連絡先帳復元」機能を使用します。WeChat には、この機能を通じて以前に削除した連絡先をすばやく復元できる「連絡先帳復元」機能が用意されています。 3. WeChat 設定ページに入り、右下隅をクリックし、WeChat アプリケーション「Me」を開き、右上隅にある設定アイコンをクリックして設定ページに入ります。

携帯電話が人々の日常生活において重要なツールになるにつれて、フォント サイズの設定は重要なパーソナライゼーション要件になりました。さまざまなユーザーのニーズを満たすために、この記事では、簡単な操作で携帯電話の使用体験を向上させ、携帯電話のフォントサイズを調整する方法を紹介します。携帯電話のフォント サイズを調整する必要があるのはなぜですか - フォント サイズを調整すると、テキストがより鮮明で読みやすくなります - さまざまな年齢のユーザーの読書ニーズに適しています - フォント サイズを使用すると、視力の悪いユーザーにとって便利です携帯電話システムの設定機能 - システム設定インターフェイスに入る方法 - 設定インターフェイスで「表示」オプションを見つけて入力します。 - 「フォント サイズ」オプションを見つけて、サードパーティでフォント サイズを調整します。アプリケーション - フォント サイズの調整をサポートするアプリケーションをダウンロードしてインストールします - アプリケーションを開いて、関連する設定インターフェイスに入ります - 個人に応じて

テクノロジーの発展に伴い、モバイルゲームは人々の生活に欠かせないものになりました。かわいいドラゴンエッグの画像と面白い孵化過程で多くのプレイヤーの注目を集めており、その中でも注目を集めているゲームの一つがモバイル版ドラゴンエッグです。プレイヤーがゲーム内で自分のドラゴンをより適切に育成し成長させることができるように、この記事ではモバイル版でドラゴンの卵を孵化させる方法を紹介します。 1. 適切な種類のドラゴン エッグを選択する プレイヤーは、ゲーム内で提供されるさまざまな種類のドラゴン エッグの属性と能力に基づいて、自分に適したドラゴン エッグの種類を慎重に選択する必要があります。 2. 孵化機のレベルをアップグレードします。プレイヤーはタスクを完了し、小道具を収集することで孵化機のレベルを向上させる必要があります。孵化機のレベルは孵化速度と孵化成功率を決定します。 3. プレイヤーはゲームに参加する必要がある孵化に必要なリソースを収集します。

Java フレームワークと React フレームワークの統合: 手順: バックエンド Java フレームワークをセットアップします。プロジェクト構造を作成します。ビルドツールを設定します。 React アプリケーションを作成します。 REST API エンドポイントを作成します。通信メカニズムを構成します。実際のケース (SpringBoot+React): Java コード: RESTfulAPI コントローラーを定義します。 React コード: API によって返されたデータを取得して表示します。

時間計算量は、入力のサイズに対するアルゴリズムの実行時間を測定します。 C++ プログラムの時間の複雑さを軽減するためのヒントには、適切なコンテナー (ベクター、リストなど) を選択して、データのストレージと管理を最適化することが含まれます。クイックソートなどの効率的なアルゴリズムを利用して計算時間を短縮します。複数の操作を排除して二重カウントを削減します。条件分岐を使用して、不必要な計算を回避します。二分探索などのより高速なアルゴリズムを使用して線形探索を最適化します。

スマートフォンの普及に伴い、携帯フィルムは欠かせないアクセサリーの一つとなりました。耐用年数を延ばすには、携帯電話の画面を保護する適切な携帯電話フィルムを選択してください。この記事では、読者が自分に最適な携帯電話フィルムを選択できるように、携帯電話フィルムを購入する際のいくつかのポイントとテクニックを紹介します。携帯電話フィルムの素材と種類を理解する:PET フィルム、TPU など。 携帯電話フィルムは強化ガラスを含むさまざまな素材でできています。 PETフィルムは比較的柔らかく、強化ガラスフィルムは耐傷性に優れ、TPUは耐衝撃性能に優れています。選択する際は、個人の好みやニーズに基づいて決定できます。画面の保護の程度を考慮してください。携帯電話のフィルムの種類によって、画面の保護の程度も異なります。 PETフィルムは主に傷防止の役割を果たしますが、強化ガラスフィルムは落下耐性に優れています。より良いものを選ぶことができます

シミは、首や手の甲などの露出している部分の高齢者の顔に現れる傾向がある一般的な皮膚の問題です。また、見た目に問題を引き起こすだけでなく、老けて見えることもあります。しかし、科学技術の進歩と美容技術の発展により、シミを簡単かつ迅速に除去する方法がたくさんあります。若くて健康な肌を取り戻し、シミを早く解消するために、この記事では効果的なスキンケアのヒントをいくつか紹介します。 1. 紫外線ダメージから積極的に肌を守ることの重要性 シミの主な原因の一つである紫外線を長時間日光にさらさないことが非常に重要です。 2. スキンケア製品を合理的に選択し、抗酸化物質と美白成分を含む製品を使用することで、シミの発生を軽減できます。

PHP 関数の効率を最適化する 5 つの方法: 変数の不必要なコピーを避ける。参照を使用して変数のコピーを回避します。繰り返しの関数呼び出しを避けてください。単純な関数をインライン化します。配列を使用したループの最適化。
