ホームページ > 記事 > ウェブフロントエンド > 仮想 DOM と Ref を使用した効率的な DOM 操作
高速で応答性の高いウェブサイトの秘密
お気に入りの Web サイトがなぜこれほど高速で応答性が高いのか疑問に思ったことはありますか?すべては、DOM 操作をどのように処理するかにかかっています。ドキュメント オブジェクト モデル (DOM) は、Web ページを構造化されたツリーとして表します。従来は、getElementById や RemoveChild などの JavaScript メソッドを使用して変更を行っていました。しかし、Web サイトが複雑になるにつれて、これらの方法では処理の速度が低下する可能性があります。革新的な仮想 DOM を備えた React の登場です。
従来の DOM 操作の課題
DOM を、多数の枝を持つ巨大なツリーと考えてください。 10 個のリストの最初の項目を更新するなど、何かを変更するたびに、ツリー全体を揺さぶることになります。これにより、特に Web ページがより複雑になると、処理が遅くなる可能性があります。ブランチ (要素) が増えるほど、すべてをスムーズに実行し続けることが難しくなります。
React のソリューション: 仮想 DOM
React は、HTML DOM の軽量コピーである Virtual DOM を使用してこの問題に対処します。変更は最初に仮想 DOM に適用され、次に React は実際の DOM を効率的に更新してこれらの変更を反映します。調整として知られるこのプロセスにより、DOM の必要な部分のみが更新されるようになり、パフォーマンスが大幅に向上します。
仮想 DOM の仕組み
React で JSX 要素をレンダリングすると、仮想 DOM 全体が更新されます。これは非効率的に聞こえるかもしれませんが、実際の DOM を直接操作するよりも高速です。その理由は次のとおりです。React は、更新を行う前に Virtual DOM のコピーを作成します。次に、Diffing と呼ばれるプロセスを使用して、更新された仮想 DOM とこのコピーを比較します。この比較により、変更された特定の要素が特定され、React は実際の DOM 内のそれらの要素のみを更新します。
内部: React の差分アルゴリズム
React の差分アルゴリズムは、効率的な DOM 更新の背後にある秘密のソースです。このアルゴリズムは、Virtual DOM の 2 つのバージョンを比較し、それらを同期するために必要な最小限の変更セットを適用します。
2 つのツリーのルート要素のタイプが異なる場合、React はツリー全体を再構築します。たとえば、
<div> <Tree/> </div> <span> <Tree/> </span>
ルート要素 (div と span) が異なるため、React はツリー全体を再構築します。
同じ要素タイプ
<span id="span1" /> <span id="span2" />
ここでは、React は id 属性のみを更新し、残りの要素はそのまま残します。
子要素の比較
React は子要素への更新も最適化します。次のリストを検討してください:
<ul> <li>Child1</li> <li>Child2</li> </ul>
<ul> <li>Child1</li> <li>Child2</li> <li>Child3</li> </ul>
React は Child3 を新規とみなし、それに応じて更新します。ただし、新しい要素が最初に追加された場合、React はリスト全体を再構築する可能性があります。ここで鍵が登場します。
アップデートの最適化におけるキーの役割
キーは、どの要素が変更、追加、削除されたかを React が追跡するのに役立ちます。これらは兄弟間で一意であり、レンダリング間で安定している必要があります。
<ul> <li key="101">Child1</li> <li key="102">Child2</li> </ul>
<ul> <li key="100">Child3</li> <li key="101">Child1</li> <li key="102">Child2</li> </ul>
この例では、React は Child3 が新しいことを認識し、リストを再構築せずに効率的に更新します。
Ref を使用した DOM の操作
React は Virtual DOM を使用して DOM 更新を最適化しますが、入力のフォーカス、特定の要素へのスクロール、要素の寸法の測定など、DOM 要素の直接操作が必要なシナリオもあります。 React はこの目的のために useRef フックを提供します。 ref を作成し、ref 属性を介して DOM 要素にアタッチすると、DOM ノードに直接アクセスできます。 useRef フックは、現在のプロパティを持つオブジェクトを返します。このプロパティは、最初は null ですが、レンダリングされると DOM ノードが割り当てられます。これにより、要素上でネイティブ DOM メソッドを直接呼び出すことができ、特定のインタラクションの制御が強化されます。たとえば、myRef.current.scrollIntoView() を使用して要素をスクロールして表示できます。
例: 色を変える Div
これを実際に見てみるための楽しい例を作成してみましょう。ボタンをクリックすると色が変わるdivを作成します。クラスベースのコンポーネントと ref を使用して、div のスタイルを直接操作します。
<div id="root"></div>
const root = ReactDOM.createRoot(document.getElementById('root')); class ColorChanger extends React.Component { constructor(props) { super(props); this.divRef = React.createRef(); this.colors = ['#FFCDD2', '#C8E6C9', '#BBDEFB', '#FFF9C4', '#D1C4E9']; this.state = { colorIndex: 0 }; this.changeColor = this.changeColor.bind(this); } changeColor() { const nextColorIndex = (this.state.colorIndex + 1) % this.colors.length; this.setState({ colorIndex: nextColorIndex }); this.divRef.current.style.backgroundColor = this.colors[nextColorIndex]; } render() { return ( <div className="container"> <div ref={this.divRef} className="color-box" style={{ backgroundColor: this.colors[this.state.colorIndex], }} ></div> <button onClick={this.changeColor}>Change Color</button> </div> ); } } root.render(<ColorChanger />);
説明
ルートの作成: React アプリのルートは ReactDOM.createRoot(document.getElementById('root')) を使用して作成されます。
ColorChanger コンポーネント:
コンストラクター: React.createRef() で ref を初期化し、色の配列を設定し、カラー インデックスを追跡するために状態を初期化します。
changeColor メソッド: 次のカラー インデックスを計算し、状態を更新し、DOM を直接操作して div の背景色を変更します。
レンダリング メソッド: div とボタンをレンダリングし、ref を div にアタッチし、ボタンの onClick ハンドラーをchangeColor に設定します。
コンポーネントのレンダリング: ColorChanger コンポーネントはルート要素にレンダリングされます。
結論
React の Virtual DOM は Web 開発に大きな変革をもたらし、アプリの効率と応答性を高めます。 React は Virtual DOM を活用することで、DOM の必要な部分のみが更新されるようにし、パフォーマンスを向上させます。 React の差分アルゴリズムとキーがどのように機能するかを理解すると、よりスムーズで高速な React アプリケーションを作成するのに役立ちます。正確な制御が必要な場合は、React の ref が DOM との直接対話を支援します。 Virtual DOM のパワーを活用して、Web 開発スキルを次のレベルに引き上げましょう!
以上が仮想 DOM と Ref を使用した効率的な DOM 操作の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。