どうも、フロントエンドエンジニアのRYOです。
米Facebook社が社名を改め、Meta社となりましたね。
Metaの由来はメタバースという言葉から来ており、仮想空間及びそこで展開されるコンテンツの総称であるとか。
VR機器で知られるOculus社を買収した頃から見据えていた仮想技術に本格的に腰を据えていくという姿勢を感じます。
そんなMeta社ですが旧社名時代から仮想という概念を採用した有名なJavaScriptライブラリをリリースしていますよね。
そう、仮想DOM(Virtual DOM)を採用したReactです。
今回はReactの仮想DOMについて理解を深めるというテーマでお送りします。
※本記事は筆者の経験及び、公式サイトの解説から解釈した内容であることをご理解いただきますようお願いします。
Reactの特徴として宣言的なViewがあります。
これはアプリケーションを状態(state)という概念で定義し、その状態に対してUI(view)を作るということです。
もっと噛み砕いて解説しましょう。
例えばウェブサイトでよく見るハンバーガーメニュー(クリックすることでメニューを開閉する機能を持つボタン)がありますね。
ハンバーガーメニューが実装されたサイトは少なくとも以下2つの状態を持ちます。
これをReactを用いる場合とそうでない場合で実装してみましょう。
Reactを用いず、素のJavsScriptで実装してみます。
HTML側の記述(UI部分)
<div id="js-menu" style="display:none"> メニュー画面 </div> <button id="js-menu-btn"> メニューを表示するボタン </button>
JavaScript側の記述(ロジック部分)
const menuElement = document.getElementById("js-menu") // メニュー画面の要素 const btnElement = document.getElementById("js-menu-btn") // 開閉ボタンの要素 let flg = false // 開閉の判断に使うフラグ変数 btnElement.addEventListener("click", () => { if (flg) { menuElement.style.display = "none" flg = false } else { menuElement.style.display = "block" flg = true } })
上記の記述でボタンをクリックすることでメニュー要素の開閉が可能になりました。この実装はDOM要素に対してJSで要素を選択し、CSSを書き換えるという手順を踏んでいます。つまりUIとロジックが密接に結びついていると言えますね。素のJavsScriptを用いる場合は一般的な実装方法でしょう。
これに対してReactによる実装を見てみます。
Reactではjsファイル内にJSXと呼ばれるHTMLタグに酷似した言語を使用できます。 これは後述する仮想DOMとして変換されます。
Reactの記述
const Menu = () => { const [flg, setFlg] = useState(false) // メニュー画面の状態を定義 const clickHandler = () => setFlg(!flg) // 開閉ボタンクリック時に実行する関数 return ( <> <div style={{display: flg ? "block" : "none"}}> メニュー画面 </div> <button onClick={clickHandler}> メニューを表示するボタン </button> </> ) }
上記の記述ではisOpen変数に代入したbool値を用いてメニュー要素の状態を定義しました。これも先ほどと同様、ボタンクリックでメニューが開閉します。
上記2つの例の違いがわかりますでしょうか?
Reactを用いない場合では既存の要素に対して命令的にJSでDOM操作を行うのに対し、一方では要素のあるべき状態をすでに宣言した形となります。
これがReactの最も大きな特徴である宣言的なViewです。宣言的なViewで実装することで命令的なDOM操作に比べ、UIとロジックの分離がされているのでコードの見通しが良くなります。Reactは従来の命令的なDOM操作に伴う苦痛に対する解決策の一つとなり得ますね。
さて、この宣言的なViewですがどのような仕組みで実装されてるのでしょうか?
仮想DOM(以下、VDOM)とはDOMの構造を純粋なJavaScriptオブジェクトで表現した構造体です。宣言的なViewはVDOMの実装、及び概念の上に成り立ちます。 ReactはこのVDOMを内部に保持し、その構造をブラウザ上のDOMに反映することでUIを生成しています。
仕組みとしてはVDOMはReact内部に2つ存在し、一方で状態の更新が行われるとFiber Reconcealerと呼ばれる差分検出アルゴリズムがVDOMの新旧を比較、差分を検出してブラウザ上のDOMに差分を反映しています。
そのため最短かつ効率の良いDOMの更新処理を行うことができるわけですね。
今回はReactの仮想DOMについて解説しました。
仮想DOMはReactのコアな実装であるため、仕組みを理解しておくと有効に活用できると思います。
弊社MONSTER DIVEではフロントエンドエンジニアを募集しています。
新しいことに挑戦したり、技術を突き詰めていく社内環境が整っていますので多くの学びや経験が得られます。新鮮気鋭の若手エンジニアさんも技術を突き詰めたいエンジニアさんも大歓迎です。興味を持っていただけた方はこちらから募集要項をご覧ください。