最新の Web アプリケーションを構築する場合、アプリの高速性と応答性を維持するには、UI (ユーザー インターフェイス) を効率的に更新することが不可欠です。多くのフレームワーク (React など) で使用される一般的な戦略は、仮想 DOM と コンポーネント を使用することです。この記事では、仮想 DOM を使用してコンポーネントがどのようにレンダリングされるか、またウェブ アプリが遅くならないように 再レンダリングを最適化する方法について説明します。
DOM (ドキュメント オブジェクト モデル) は、Web ページ上のすべての要素を表すツリー状の構造です。ボタンをクリックしたりテキストを入力したりして Web ページを操作するたびに、ブラウザは DOM を更新する必要があり、時間がかかる場合があります。
仮想 DOM は実際の DOM のコピーに似ていますが、メモリ内にのみ存在します。何かが変更されるたびに実際の DOM を直接更新するのではなく、最初に仮想 DOM を更新します。変更が加えられると、仮想 DOM はそれ自体を古いバージョンと比較し、相違点を見つけ (これを 差分 と呼びます) し、変更が必要な実際の DOM の部分のみを更新します。
最新の Web アプリでは、コンポーネントが UI の構成要素です。これらは、Web ページの再利用可能な小さな部分であると考えてください。例えば:
各コンポーネントは、UI のどの部分がどのように見えるべきかを記述します。 コンポーネント関数は、その UI を表す 仮想 DOM ツリーを返します。
疑似コードを使用して、単純な Button コンポーネントを作成してみましょう。このコンポーネントは、テキストを含むボタンと、ボタンがクリックされたときに実行される関数を返します。
// Component to display a button function Button(props) { // The Button component returns a Virtual DOM node for a
この例では:
ヘッダーとボタンを持つアプリを構築したいとします。これらの各部分はコンポーネントとして表すことができます。アプリの構造は次のようになります:
// App component with a header and button function App() { return new VirtualNode("div", {}, [ new Header(), // The Header component new Button({ text: "Click Me", onClick: handleClick }) // The Button component ]) } // Header component function Header() { return new VirtualNode("h1", {}, ["Welcome to the App!"]) } // Function to handle button clicks function handleClick() { console.log("Button clicked!") }
アプリを初めて実行すると、次のようになります:
// Initial render of the app function renderApp() { let virtualDOM = App() // Render the app's Virtual DOM let realDOM = createRealDOM(virtualDOM) // Convert the Virtual DOM into real DOM elements attachToPage(realDOM) // Attach the real DOM elements to the webpage }
ボタンのテキストなど、アプリ内の何かが変更されたとします。通常、アプリ全体が再レンダリングされますが、アプリが大きい場合、これは遅くなる可能性があります。代わりに、変更された部分のみを更新することで再レンダリングを最適化できます。
再レンダリングが発生すると次のようになります:
ボタンのテキストが「Click Me」から「Clicked!」に変わったとします。ボタンを再レンダリングする方法は次のとおりです:
// New Button component with updated text function Button(props) { return new VirtualNode("button", { onClick: props.onClick }, [props.text]) } // Re-rendering with the new text let oldButton = Button({ text: "Click Me", onClick: handleClick }) let newButton = Button({ text: "Clicked!", onClick: handleClick }) // Diff the old and new Button let diffResult = diff(oldButton, newButton) // Patch the real DOM with the changes patch(realButtonDOM, diffResult)
再レンダリングを最適化する重要な方法の 1 つは、コンポーネントを実際に更新する必要があるかどうかを確認することです。コンポーネントの props または state に何も変更がない場合は、そのコンポーネントの再レンダリングをスキップできます。ここで、 shouldComponentUpdate ロジックが登場します。
// Function to check if a component should update function shouldComponentUpdate(oldProps, newProps) { return oldProps !== newProps // Only update if the props have changed }
次に、再レンダリングする前に、コンポーネントを更新する必要があるかどうかを確認します:
// Example: Optimized re-rendering of Button component function renderButtonIfNeeded(oldButton, newButton) { if (shouldComponentUpdate(oldButton.props, newButton.props)) { let realButton = createRealDOM(newButton) patch(realButton) } }
項目のリスト (ボタンのリストなど) をレンダリングする場合、keys を使用して各項目を一意に識別することで最適化できます。これにより、差分アルゴリズムがリスト内の古い項目と新しい項目を照合し、必要な変更のみを適用するのに役立ちます。
// List of buttons with unique keys function ButtonList(items) { return new VirtualNode("div", {}, items.map(item => new Button({ key: item.id, text: item.text, onClick: handleClick }) )) }
キーを使用すると、リスト内の項目の 1 つが変更された場合 (ボタンの追加または削除など)、アルゴリズムは変更されたボタンをすぐに識別し、そのボタンのみを更新できます。
コンポーネントは独自の 状態を持つこともできます。コンポーネントの状態が変化したとき、アプリ全体ではなく、その特定のコンポーネントのみを再レンダリングする必要があります。以下は状態を含むボタンの例です:
// Button component with state function ButtonWithState() { let [clicked, setClicked] = useState(false) // Create state for button function handleClick() { setClicked(true) // Update state when clicked } return new VirtualNode("button", { onClick: handleClick }, [clicked ? "Clicked!" : "Click Me"]) }
この場合:
もう 1 つの最適化は、子コンポーネントのみが変更された場合に親コンポーネントの再レンダリングを回避することです。たとえば、ボタンが変更されてもヘッダーが同じままの場合、ヘッダーの再レンダリングをスキップできます。
// Optimized App component function App() { if (!shouldComponentUpdate(oldHeaderProps, newHeaderProps)) { return oldHeader // Reuse the old Header if it hasn't changed } return new VirtualNode("div", {}, [ new Header(), // Re-render the Header only if necessary new ButtonWithState() // Button re-renders based on state ]) }
要約すると、仮想 DOM を使用してコンポーネントをレンダリングおよび最適化するプロセスを次のステップに分けることができます:
いつ、何を再レンダリングするかを慎重に考えることで、Web アプリケーションが複雑になっても効率を維持できるようになります。 Virtual DOM は、シンプルさとパフォーマンスのバランスを実現するのに役立つ強力なツールです!
免責事項: 提供されるすべてのリソースの一部はインターネットからのものです。お客様の著作権またはその他の権利および利益の侵害がある場合は、詳細な理由を説明し、著作権または権利および利益の証拠を提出して、電子メール [email protected] に送信してください。 できるだけ早く対応させていただきます。
Copyright© 2022 湘ICP备2022001581号-3