仮想DOMをきっかけに、React.jsがヒットした理由を探求する- JSフレームワーク × ビアバッシュ 初心者勉強会

「仮想DOMで探る、React.jsがヒットした理由」で、登壇しました。勉強会は、初心者向けのJSフレームワーク勉強会です。

sakeganaito.connpass.com

会場の風景を撮り忘れていたのですが、すごくシックで雰囲気が良かったです。写真は「好きだけじゃ辛いScala.js」の発表です。発表者は@omiendさん。

f:id:konosumi:20181215164533j:plain

Vue.js、Scala.js、Riot.js・・・さまざまなフロントエンドJSの発表がある中、私はReact.jsについて発表しました。

自分なりにまとめながら、発表の補足を書いていきます。

目次

仮想DOMで探る、Reactがヒットした理由のスライド

まず始めに、スライドを共有します。スライドのキーポイントは、「Reactは仮想DOMを採用したからこそ、高パフォーマンスを発揮している」という点です。

speakerdeck.com

スライドの解説

DOMとは何か?

DOMは「Document Object Model」の略称です。

ざっくり言ってしまえば、DOMは「ドキュメントを操作するためのインターフェース(=API)」を指します。Webの場合、ドキュメントはHTMLが該当します。

DOMのイメージ図

言葉で表現するとDOMは理解しづらいので、イメージ図を描きました。HTMLは、木構造や樹形図のような構造体として組み立てられています。

f:id:konosumi:20181215172025p:plain

私たち開発者は、ブラウザからJavaScriptを経由し、DOMを操作するAPIを使ってHTMLにアクセスしています。

実DOM(リアルDOM)と仮想DOMの違い

  • 実DOM(=リアルDOM): 実際にブラウザで描画されるDOMです
    • 変更すると、ブラウザに表示されているHTMLも書き換わります
    • 書き換えコスト(負荷)の高い操作です
  • 仮想DOM: メモリ空間などで、擬似的にDOMを再現した構造体です
    • 変更すると、メモリ空間上にあるデータが書き換わります
    • 書き換えコスト(負荷)の低い操作です

jQueryとReact.jsの違いで考えてみる

  • jQueryは、ブラウザで表示されているHTML(=実DOM)を操作します
  • Reactは、先に仮想DOMを作り、実DOMとの差分を計算します。差分だけをHTMLに適用します

Reactの特徴は、実DOMの書き換えに仮想DOMを経由していることです。Reactは、仮想DOMと実DOMの差分を事前に計算することで、最適化された最小コストでHTMLを変更しています。

つまり、高いパフォーマンスを発揮するのです。

Reactは差分検知のアルゴリズムだから他の分野に応用できる

Reactは、仮想DOMと実DOMの差分を計算しています。ゆえに、「Reactは差分検知のアルゴリズムである」といっても、過言ではありません。

React.jsは、ReactをWebの世界に適用した実装です。しかしながら、単なるアルゴリズムであれば、他への応用も考えられます。

「React Native(モバイルアプリ)」や「React VR(VR空間)」は、その一例です。Reactが対象とするDOMはHTMLに限らないので、今後も新たな「React~~」が誕生するかもしれません!

Reactのパフォーマンスを上げるには?

Reactは、stateなどの値の状態変化に起因して、仮想DOMを再構成しています。

Reactアプリケーションでパフォーマンスを上げるコツは、再レンダリングの回数を抑えることです。つまり、仮想DOMを再構成する回数を節約すると、Reactのパフォーマンスを上げることができます。

Qiitaの「ReactでshouldComponentUpdateを使ったチューニングの効果と注意どころ」は、とても参考になる記事です。wordijpさん、ありがとうございます。

qiita.com

「shouldComponentUpdate」では、falseを返すと仮想DOMの再レンダリングがキャンセルされます。DOM(要は見た目)に影響しないstateの変更は、仮想DOMを再構成する意味がありません。

描画に関わるstateが変更されたときだけtrueを返し、仮想DOMを再レンダリングしパフォーマンスを最適化するアプローチです。

shouldComponentUpdate: function(nextProps, nextState) {
  if (/* 差分があるか判定します */) {
    return true;
  }
  else {
    return false;
  }
}

Fluxによる状態の集約

HTMLが書き換わるまでの流れを理解すると、Fluxを理解しやすくなります。

  1. 現在の状態(state)が変わる
  2. 再レンダリング(仮想DOMの再構成)を実行する
  3. 実DOMとの差分を計算する
  4. 実際にHTML(=実DOM)を書き換える

Fluxは、「1. 現在の状態」を集約して管理するためのアーキテクチャです。

現在の状態を個々のReactコンポーネントが持ってしまうと、管理が複雑になってしまいます。そこで、状態を一箇所にしようという発想が生まれました。

React.jsでよく使われるReduxも、Fluxの思想を反映したフレームワークです。

さいごに

React.jsは、仮想DOMを採用することで、優れたパフォーマンスを発揮しています。これは間違いなく、ヒットした理由のひとつです。

また、仮想DOMの技術を知っておくと、フロントエンドJSがどのようにHTMLを書き換えているのかイメージしやすくなります。Reactコンポーネントのrenderは、仮想DOMを作っていたのです。

最後に御礼ですが、「【第5回】JSフレームワーク(またはライブラリ)× ビアバッシュ 初心者勉強会 in西新宿」は、とても雰囲気の良いイベントでした。貴重な機会を提供してくださった運営の皆様、および私のプレゼンを聞いてくださった皆様に、深く感謝いたします。

参考文献

本記事の内容は、「WEB+DB PRESS Vol.106」の「仮想DOM革命 ReactでGUI設計が変わる!」で得た知見をベースにしています。

過去にブログで感想記事も書いてますので、もし宜しければごらんください。

www.konosumi.net

WEB+DB PRESS Vol.106

WEB+DB PRESS Vol.106

  • 作者: 成田元輝,杉浦颯太,小和瀬塁,山中大輔,末田正樹,藤野真聡,竹馬光太郎,桑原仁雄,倉長拓海,牧大輔,秋山卓巳,前田雅央,星北斗,末永恭正,久保田祐史,池田拓司,はまちや2,竹原,WEB+DB PRESS編集部
  • 出版社/メーカー: 技術評論社
  • 発売日: 2018/08/24
  • メディア: 単行本
  • この商品を含むブログを見る