tag:crieit.net,2005:https://crieit.net/tags/React.js/feed 「React.js」の記事 - Crieit Crieitでタグ「React.js」に投稿された最近の記事 2018-12-17T12:16:36+09:00 https://crieit.net/tags/React.js/feed tag:crieit.net,2005:PublicArticle/14663 2018-12-16T14:07:35+09:00 2018-12-17T12:16:36+09:00 https://crieit.net/posts/DOM-React-js-JS 仮想DOMをきっかけに、React.jsがヒットした理由を探求する- JSフレームワーク × ビアバッシュ 初心者勉強会 <p>「仮想DOMで探る、React.jsがヒットした理由」で、登壇しました。勉強会は、初心者向けのJSフレームワーク勉強会です。</p> <p><a target="_blank" rel="nofollow noopener" href="https://sakeganaito.connpass.com/event/108628/" target="_blank" rel="noopener">【第5回】JSフレームワーク(またはライブラリ)× ビアバッシュ 初心者勉強会 in西新宿 - connpass</a></p> <p>会場の風景を撮り忘れていたのですが、すごくシックで雰囲気が良かったです。写真は「好きだけじゃ辛いScala.js」の発表です。発表者は<a target="_blank" rel="nofollow noopener" href="https://twitter.com/omiend">@omiend</a>さん。</p> <p><a href="https://crieit.now.sh/upload_images/7e2145237c1fd22de733084e60f7fee85c15dca4b9d33.jpg" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/7e2145237c1fd22de733084e60f7fee85c15dca4b9d33.jpg?mw=700" alt="image" /></a></p> <p>Vue.js、Scala.js、Riot.js・・・さまざまなフロントエンドJSの発表がある中、私はReact.jsについて発表しました。</p> <p>自分なりにまとめながら、発表の補足を書いていきます。</p> <h2 id="仮想DOMで探る、Reactがヒットした理由のスライド"><a href="#%E4%BB%AE%E6%83%B3DOM%E3%81%A7%E6%8E%A2%E3%82%8B%E3%80%81React%E3%81%8C%E3%83%92%E3%83%83%E3%83%88%E3%81%97%E3%81%9F%E7%90%86%E7%94%B1%E3%81%AE%E3%82%B9%E3%83%A9%E3%82%A4%E3%83%89">仮想DOMで探る、Reactがヒットした理由のスライド</a></h2> <p>まず始めに、スライドを共有します。スライドのキーポイントは、 <strong>「Reactは仮想DOMを採用したからこそ、高パフォーマンスを発揮している」</strong> という点です。</p> <p><a target="_blank" rel="nofollow noopener" href="https://speakerdeck.com/konosumi/virtual-dom-react-hit">https://speakerdeck.com/konosumi/virtual-dom-react-hit</a></p> <h2 id="スライドの解説"><a href="#%E3%82%B9%E3%83%A9%E3%82%A4%E3%83%89%E3%81%AE%E8%A7%A3%E8%AA%AC">スライドの解説</a></h2> <h3 id="DOMとは何か?"><a href="#DOM%E3%81%A8%E3%81%AF%E4%BD%95%E3%81%8B%EF%BC%9F">DOMとは何か?</a></h3> <p>DOMは「Document Object Model」の略称です。</p> <p>ざっくり言ってしまえば、DOMは<strong>「ドキュメントを操作するためのインターフェース(=API)」</strong>を指します。Webの場合、ドキュメントはHTMLが該当します。</p> <h3 id="DOMのイメージ図"><a href="#DOM%E3%81%AE%E3%82%A4%E3%83%A1%E3%83%BC%E3%82%B8%E5%9B%B3">DOMのイメージ図</a></h3> <p>言葉で表現するとDOMは理解しづらいので、イメージ図を描きました。HTMLは、 <strong>木構造や樹形図のような構造体</strong> として組み立てられています。</p> <p><a href="https://crieit.now.sh/upload_images/f3bd9a250a0a8671f9abe0985d00d9455c15dccb2780f.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/f3bd9a250a0a8671f9abe0985d00d9455c15dccb2780f.png?mw=700" alt="image" /></a></p> <p>私たち開発者は、ブラウザからJavaScriptを経由し、DOMを操作するAPIを使ってHTMLにアクセスしています。</p> <h3 id="実DOM(リアルDOM)と仮想DOMの違い"><a href="#%E5%AE%9FDOM%28%E3%83%AA%E3%82%A2%E3%83%ABDOM%29%E3%81%A8%E4%BB%AE%E6%83%B3DOM%E3%81%AE%E9%81%95%E3%81%84">実DOM(リアルDOM)と仮想DOMの違い</a></h3> <ul> <li>実DOM(=リアルDOM): <strong>実際にブラウザで描画されるDOM</strong> です <ul> <li>変更すると、ブラウザに表示されているHTMLも書き換わります</li> <li>書き換えコスト(負荷)の高い操作です</li> </ul></li> <li>仮想DOM: メモリ空間などで、<strong>擬似的にDOMを再現した構造体</strong> です <ul> <li>変更すると、メモリ空間上にあるデータが書き換わります</li> <li>書き換えコスト(負荷)の低い操作です</li> </ul></li> </ul> <h3 id="jQueryとReact.jsの違いで考えてみる"><a href="#jQuery%E3%81%A8React.js%E3%81%AE%E9%81%95%E3%81%84%E3%81%A7%E8%80%83%E3%81%88%E3%81%A6%E3%81%BF%E3%82%8B">jQueryとReact.jsの違いで考えてみる</a></h3> <ul> <li>jQueryは、ブラウザで表示されているHTML(=実DOM)を操作します</li> <li>Reactは、先に仮想DOMを作り、実DOMとの差分を計算します。差分だけをHTMLに適用します</li> </ul> <p>Reactの特徴は、実DOMの書き換えに仮想DOMを経由していることです。Reactは、 <strong>仮想DOMと実DOMの差分を事前に計算する</strong> ことで、最適化された最小コストでHTMLを変更しています。</p> <p>つまり、高いパフォーマンスを発揮するのです。</p> <h3 id="Reactは差分検知のアルゴリズムだから他の分野に応用できる"><a href="#React%E3%81%AF%E5%B7%AE%E5%88%86%E6%A4%9C%E7%9F%A5%E3%81%AE%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0%E3%81%A0%E3%81%8B%E3%82%89%E4%BB%96%E3%81%AE%E5%88%86%E9%87%8E%E3%81%AB%E5%BF%9C%E7%94%A8%E3%81%A7%E3%81%8D%E3%82%8B">Reactは差分検知のアルゴリズムだから他の分野に応用できる</a></h3> <p>Reactは、仮想DOMと実DOMの差分を計算しています。ゆえに、 <strong>「Reactは差分検知のアルゴリズムである」</strong> といっても、過言ではありません。</p> <p>React.jsは、ReactをWebの世界に適用した実装です。しかしながら、単なるアルゴリズムであれば、他への応用も考えられます。</p> <p>「React Native(モバイルアプリ)」や「React VR(VR空間)」は、その一例です。Reactが対象とするDOMはHTMLに限らないので、今後も新たな「React~~」が誕生するかもしれません!</p> <h3 id="Reactのパフォーマンスを上げるには?"><a href="#React%E3%81%AE%E3%83%91%E3%83%95%E3%82%A9%E3%83%BC%E3%83%9E%E3%83%B3%E3%82%B9%E3%82%92%E4%B8%8A%E3%81%92%E3%82%8B%E3%81%AB%E3%81%AF%EF%BC%9F">Reactのパフォーマンスを上げるには?</a></h3> <p>Reactは、stateなどの値の状態変化に起因して、仮想DOMを再構成しています。</p> <p>Reactアプリケーションでパフォーマンスを上げるコツは、再レンダリングの回数を抑えることです。つまり、 <strong>仮想DOMを再構成する回数を節約</strong> すると、Reactのパフォーマンスを上げることができます。</p> <p>Qiitaの「ReactでshouldComponentUpdateを使ったチューニングの効果と注意どころ」は、とても参考になる記事です。wordijpさん、ありがとうございます。</p> <p><a target="_blank" rel="nofollow noopener" href="https://qiita.com/wordijp/items/cfda7bbad195eec22cc3" target="_blank" rel="noopener">ReactでshouldComponentUpdateを使ったチューニングの効果と注意どころ #React - Qiita</a></p> <p>「shouldComponentUpdate」では、falseを返すと <strong>仮想DOMの再レンダリングがキャンセル</strong> されます。DOM(要は見た目)に影響しないstateの変更は、仮想DOMを再構成する意味がありません。</p> <p>描画に関わるstateが変更されたときだけtrueを返し、仮想DOMを再レンダリングしパフォーマンスを最適化するアプローチです。</p> <pre><code class="js">shouldComponentUpdate: function(nextProps, nextState) { if (/* 差分があるか判定します */) { return true; } else { return false; } } </code></pre> <h3 id="Fluxによる状態の集約"><a href="#Flux%E3%81%AB%E3%82%88%E3%82%8B%E7%8A%B6%E6%85%8B%E3%81%AE%E9%9B%86%E7%B4%84">Fluxによる状態の集約</a></h3> <p>HTMLが書き換わるまでの流れを理解すると、Fluxを理解しやすくなります。</p> <ol> <li>現在の状態(state)が変わる</li> <li>再レンダリング(仮想DOMの再構成)を実行する</li> <li>実DOMとの差分を計算する</li> <li>実際にHTML(=実DOM)を書き換える</li> </ol> <p>Fluxは、「1. 現在の状態」を集約して管理するためのアーキテクチャです。</p> <p>現在の状態を個々のReactコンポーネントが持ってしまうと、管理が複雑になってしまいます。そこで、 <strong>状態を一箇所にしようという発想</strong> が生まれました。</p> <p>React.jsでよく使われるReduxも、Fluxの思想を反映したフレームワークです。</p> <h2 id="さいごに"><a href="#%E3%81%95%E3%81%84%E3%81%94%E3%81%AB">さいごに</a></h2> <p>React.jsは、仮想DOMを採用することで、優れたパフォーマンスを発揮しています。これは間違いなく、ヒットした理由のひとつです。</p> <p>また、仮想DOMの技術を知っておくと、 <strong>フロントエンドJSがどのようにHTMLを書き換えているのか</strong> イメージしやすくなります。Reactコンポーネントのrenderは、仮想DOMを作っていたのです。</p> <p>最後に御礼ですが、「<a target="_blank" rel="nofollow noopener" href="https://sakeganaito.connpass.com/event/108628/">【第5回】JSフレームワーク(またはライブラリ)× ビアバッシュ 初心者勉強会 in西新宿</a>」は、とても雰囲気の良いイベントでした。貴重な機会を提供してくださった運営の皆様、および私のプレゼンを聞いてくださった皆様に、深く感謝いたします。</p> <h2 id="参考文献"><a href="#%E5%8F%82%E8%80%83%E6%96%87%E7%8C%AE">参考文献</a></h2> <p>本記事の内容は、「WEB+DB PRESS Vol.106」の <strong>「仮想DOM革命 ReactでGUI設計が変わる!」</strong> で得た知見をベースにしています。</p> <p>過去にブログで感想記事も書いてますので、もし宜しければごらんください。</p> <p><a target="_blank" rel="nofollow noopener" href="https://www.konosumi.net/entry/2018/08/25/020111" target="_blank" rel="noopener">仮想DOMのメリットと、リアルDOMとの違い - WEB+DB PRESS Vol.106 仮想DOM革命 - このすみノート</a></p> このすみ