web-dev-qa-db-ja.com

ReactのVirtual DOMの概念が、ダーティモデルチェックよりもプロパティが高いと言われているのはなぜですか?

私は React devの話を http://www.youtube.com/watch?v=x7cQ3mrcKaY とスピーカーは、モデルのダーティチェックは遅くなる可能性があると述べました。しかし、ほとんどの場合、仮想DOMはモデルよりも大きくなければならないため、仮想DOM間の差分の計算は実際にはそれほどパフォーマンスが低下しませんか。

私はVirtual DOMの潜在的な力(特にサーバーサイドレンダリング)が本当に好きですが、長所と短所をすべて知りたいのです。

344
Daniil

私は virtual-dom モジュールの主な作者ですので、あなたの質問に答えることができるかもしれません。ここで解決する必要がある2つの問題が実際にあります

  1. いつ再レンダリングしますか。 回答:データが汚れていることがわかりました。
  2. どのようにしたら効率的に再レン​​ダリングできますか? 答え:仮想DOMを使って実際のDOMパッチを生成する

Reactでは、あなたの各コンポーネントは状態を持っています。この状態は、ノックアウトライブラリや他のMVVMスタイルのライブラリに見られるような観察可能なものです。本質的に、Reactはシーンを再レンダリングするために when を知っています。なぜなら、このデータがいつ変わるかを観察することができるからです。定期的にデータをポーリングし、データ構造内のすべての値を再帰的に確認する必要があるため、ダーティチェックは監視可能データよりも時間がかかります。比較すると、状態に値を設定するとリスナーに何らかの状態が変化したことを知らせるので、Reactは単に状態の変化イベントをリッスンして再レンダリングをキューに入れることができます。

仮想DOMは、DOMの効率的な再レンダリングに使用されます。これはデータのダーティチェックとは関係ありません。ダーティチェックの有無にかかわらず、仮想DOMを使用して再レンダリングできます。 2つの仮想ツリー間の差分を計算するのにオーバーヘッドがあるというのは正しいのですが、仮想DOM差分は、データが変更されたかどうかではなく、DOMで更新が必要なものを理解することに関するものです。実際、 diffアルゴリズムはそれ自体がダーティチェッカーです しかしDOMがダーティであるかどうかを確認するために使用されます。

状態が変化したときだけ仮想ツリーを再レンダリングすることを目指しています。そのため、オブザーバブルを使用して状態が変化したかどうかを確認することは、不要な再レンダリングを防ぐための効率的な方法です。何も変わっていなければ、何もしません。

仮想DOMは、まるでシーン全体を再レンダリングしているかのようにコードを書くことができるので、素敵です。舞台裏では、DOMを更新して期待どおりに見えるようにするパッチ操作を計算したいと思います。そのため、仮想DOM diff/patchアルゴリズム はおそらく最適な解決策ではありません 、それは私たちのアプリケーションを表現するための非常に素晴らしい方法です。欲しいものを正確に宣言するだけで、React/virtual-domはシーンをこのようにする方法を考え出します。手動でDOMを操作したり、以前のDOMの状態について混乱したりする必要はありません。シーン全体を再レンダリングする必要もありません。パッチを適用するよりもはるかに効率が悪い場合があります。

470
Matt Esch

私は最近Reactの差分アルゴリズムに関する詳細な記事をここで読んでいます: http://calendar.perfplanet.com/2013/diff/ 。私が理解していることから、Reactを速くする理由は次のとおりです。

  • バッチDOM読み取り/書き込み操作.
  • サブツリーのみの効率的な更新.

ダーティチェックと比較すると、IMOの主な違いは次のとおりです。

  1. モデルのダーティチェックsetStateが呼ばれるときはいつでもReactコンポーネントは明示的にダーティとして設定されているので、ここでは(データの)比較は必要ありません。ダーティチェックでは、(モデルの)比較は常に各ダイジェストループで行われます。

  2. DOMの更新:DOMを変更するとCSSスタイルやレイアウトも適用および計算されるため、DOM操作は非常にコストがかかります。不必要なDOMの変更による節約時間は、仮想DOMの比較に費やされる時間よりも長くなる可能性があります。

2番目のポイントは、膨大な量のフィールドや大きなリストを持つモデルなど、重要ではないモデルにとってはさらに重要です。複雑なモデルの1つのフィールド変更は、ビュー/テンプレート全体ではなく、そのフィールドを含むDOM要素に必要な操作のみをもたらします。

128
tungd

私はVirtual DOMの潜在的な力(特にサーバーサイドレンダリング)が本当に好きですが、長所と短所をすべて知りたいのです。

- OP

Reactは唯一のDOM操作ライブラリではありません。詳細な説明とベンチマークを含むこの{ Auth0からの記事 を読んで、代替手段を理解してください。あなたが尋ねたように、私はここで彼らの賛否両論を強調します:

React.jsの仮想DOM

enter image description here

PROS

  • 高速で効率的な「拡散」アルゴリズム
  • 複数のフロントエンド(JSX、ハイパースクリプト)
  • モバイル機器で動作するのに十分な軽量
  • たくさんのトラクションとマインドシェア
  • Reactなしで(すなわち、独立したエンジンとして)使用可能

CONS

  • DOMのフルメモリコピー(より高いメモリ使用量)
  • 静的要素と動的要素を区別しない

Ember.jsのグリマー

enter image description here

PROS

  • 高速で効率的な拡散アルゴリズム
  • 静的要素と動的要素の違い
  • EmberのAPIと100%の互換性(既存のコードを大幅に更新しなくてもメリットが得られます)
  • DOMの軽量インメモリ表現

CONS

  • エンバーでのみ使用されること
  • 利用可能なフロントエンドは1つだけです

増分DOM

enter image description here

PROS

  • メモリ使用量の削減
  • 単純なAPI
  • 多くのフロントエンドやフレームワークと簡単に統合できます(最初からテンプレートエンジンバックエンドとして)

CONS

  • 他のライブラリほど速くはありません(これは議論の余地があります。下記のベンチマークを参照してください)。
  • マインドシェアやコミュニティでの使用が少ない
72
falsarella

これはReactチームメンバーのSebastianMarkbågeによるコメントです。

Reactは出力(これは既知の直列化可能フォーマット、DOM属性)を差分処理します。これは、ソースデータがどのような形式でもよいことを意味します。それは不変のデータ構造とクロージャの中の状態でありえます。

Angularモデルは参照透明性を維持しないため、本質的に変更可能です。変更を追跡するために既存のモデルを変更します。データソースが不変のデータまたは毎回新しいデータ構造(JSON応答など)の場合はどうなりますか?

ダーティーチェックとObject.observeはクロージャスコープ状態では動作しません。

これら二つのことは明らかに機能的パターンに非常に限定的です。

さらに、モデルの複雑さが増すと、ダーティトラッキングを実行することがますます高価になります。ただし、Reactのようにビジュアルツリーを単に拡散するだけでは、画面上に表示できるデータ量はUIによって制限されるため、それほど大きくはなりません。上記のPeteのリンクは、より多くの効果をカバーしています。

https://news.ycombinator.com/item?id=6937668

36
Sophie Alpert

あなたはこれを読むことができます( https://reactkungfu.com/2015/10/the-difference-between-virtual-dom-and-dom/ ) Real DOMとVirtual DOMについて知るのは芸術的です。お役に立てば幸いです。

0