FacebookのReactとWebコンポーネント(ポリマー)の長所と短所


521

今後のWebコンポーネント仕様に対するFacebookのReactの主な利点は何ですか(逆もまた同様です)(または、リンゴ同士の比較はGoogleのPolymerライブラリとなるでしょう)。

このJSConf EUトークとReactホームページによると、Reactの主な利点は次のとおりです。

  • コンポーネントモデルを使用したデカップリングと凝集度の向上
  • 抽象化、構成、表現力
  • 仮想DOMと合成イベント(基本的に、DOMとそのイベントシステムを完全に再実装したことを意味します)
    • IE 8で最新のHTML5イベントを有効にします
    • サーバー側のレンダリング
    • テスタビリティ
    • SVG、VML、およびへのバインド <canvas>

この仮想DOMの概念(明らかに)を除き、ほとんどすべてのことはWebコンポーネントを介してネイティブにブラウザーに統合されています。仮想DOMと合成イベントが古いブラウザをサポートするために今日どのように有益であるかを見ることができますが、ネイティブブラウザのコードの大部分を捨てて、長期的に足を踏み入れるようなものではありませんか?最新のブラウザに関する限り、それはホイールの不必要なオーバーヘッド/再発明の多くではありませんか?

ここに、Webコンポーネントが面倒を見てくれるReactが欠けていると思うものをいくつか紹介します。私が間違っている場合は修正してください。

  • ネイティブブラウザサポート(「より高速であることが保証されている」を参照)
  • スクリプト言語でスクリプトを記述し、スタイル言語でスタイルを記述し、マークアップ言語でマークアップを記述します。
  • Shadow DOMを使用したスタイルのカプセル化
    • 代わりにReactにはこれがあり、JavaScriptでCSSを記述する必要があります。可愛くない。
  • 双方向バインディング

12
Wrt。双方向バインディング。この機能には大規模な問題があります。些細なケースではうまく機能しますが、実際のケースでは、コードを管理しやすくするには、実際のモデルにバインドするのではなく、ビューモデルをバインドする必要があることがわかります。最初はそうでした。適切なデータフローアーキテクチャを強制するため、双方向バインディングを提供しないことがReactの利点であると思います。
ジョーリSebrechts 14

8
React、Angular、Knockoutを見てきました。Knockoutは、UIテンプレート、データ、およびバインディングの分離という点で「最もクリーン」です。私は反応が好きでしたが、単純なコンボボックスを作成しようとしていたので、html / jina2のようなものを使用するよりもはるかに多くのコードを記述し、レンダリングロジックをhtmlテンプレートと混合していました。私には、これらのライブラリ/ APIが私たちを前進させるのではなく、後退させているようです。Reactの一番の長所は仮想domの操作ですが、他の確立されたフレームワークにすぐに来ることがわかります。
mike01010

41
私は、この質問が「主に意見に基づいた」ものとしてシャットダウンされなかったことに非常に驚いています(そしてまた嬉しいです!)。
iconoclast

4
何らかのテンプレートを作成している場合、「スクリプト言語のスクリプト」と「マークアップ言語のマークアップ」を記述することはできません。角度、ポリマーなどは、HTMLに埋め込まれたテンプレートDSLを使用します。Reactは、JS(JSX)に埋め込まれたテンプレートDSLを使用します。HTMLにDSLを埋め込む際の問題は、JSから値を取得するスコープを確立する方法です。これは、Angularの複雑な$ scopeシステムにつながります。一方、JSXでは、テンプレート内の変数のスコープはJSスコープにすぎません。混乱がはるかに少ないことがわかります。
アンディ

3
現時点では、Reactコンポーネント(不適切に記述されていない限り)は、DOMにバインドされたフレームワークの場合よりも高速になります。v-domとdiff-ingマジックは、reactのUSPです。私のポイントは-なぜブラウザーはネイティブ機能セットでそのような差分を作成しないのでしょうか。何が彼らを止め、何も(彼らを止めない)なら、Reactのリードはおそらく短命になるでしょう。
fasttrainofthoughts

回答:


664

更新: この回答はかなり人気があるようですので、少し時間をかけて整理し、新しい情報を追加して、十分に明確ではないと思われるいくつかのことを明確にしました。他に説明や更新が必要だと思われる場合はコメントしてください。

あなたの懸念のほとんどは本当に意見と個人的な好みの問題ですが、私はできる限り客観的に答えようとします:

ネイティブとコンパイル済み

JavaScriptをバニラJavaScriptで記述し、CSSでCSSを記述し、HTMLでHTMLを記述します。

昔 、手作業でネイティブアセンブリを記述するか、Cのような高レベル言語を使用してコンパイラにアセンブリコードを生成させるかについての熱い議論がありました。その前でさえ、人々はアセンブラーを信頼することを拒否し、ネイティブのマシンコードを手で書くことを好みました(そして私は冗談ではありません)。

一方、今日でHTML書く人が多いHAMLジェイドに、CSSをサスまたは少ない中およびJavaScript CoffeeScriptのか、活字体で。それはそこにあります。できます。好む人もいれば嫌いな人もいます。

要点は、バニラJavaScriptでJavaScriptを、CSSでCSSを、HTMLでHTMLを記述しないことに根本的な問題はないということです。それは本当に好みの問題です。

内部DSLと外部DSL

 代わりにShadow DOM Reactを使用したスタイルのカプセル化にはこれがあり、JavaScriptでCSSを記述する必要があります。可愛くない。

かどうか、それは確かに表現力豊かです。JavaScriptは非常に強力な言語であり、CSSよりもはるかに強力です(CSSプリプロセッサを含む)。それは、これらの種類の内部DSLのどちらを優先するかによって異なります。繰り返しますが、好みの問題です。

(注:元の質問で参照されたReactインラインスタイルについて話していました。)

DSLの種類-説明

更新:回答を書いてからしばらくしてから、ここで私が意味することを説明する必要があると思います。DSLはドメイン固有の言語であり、内部(JavaScriptなどのホスト言語の構文を使用-JSXなしのReactなど、または前述のReactのインラインスタイルのような)か、外部(異なる構文を使用)のいずれかです。ホスト言語よりも-この例のように、JavaScript内でCSS(外部DSL)をインライン化します)。

一部の文献では、これらの種類のDSLを説明するために「内部」および「外部」とは異なる用語を使用しているため、混乱を招く可能性があります。「内部」の代わりに「埋め込み」が使用されることもありますが、「埋め込み」という言葉は別の意味を意味する場合があります。たとえば、Lua 「Lua:拡張可能な組み込み言語」として記述されます。それはまったく反対です-外部DSL)が、SQLiteが組み込みデータベースであるという同じ意味で埋め込まれていることを意味します。第三の意味で「e」が「組み込み」を表すeLuaもあります。組み込みシステムを意味します!eLuaのようなものは、「埋め込みDSL」ではなく、2つの異なる意味で「埋め込み」される「DSL」になる可能性があるため、「埋め込みDSL」という用語を使用するのは好きではありません。

事態を悪化させるために、一部のプロジェクトでは、さらに混乱を招きます。例えば。Flatironテンプレートは「DSLフリー」と説明されていますが、実際には次のような構文を持つ内部DSLの完璧な例です。map.where('href').is('/').insert('newurl');

そうは言っても、「JavaScriptは非常に強力な言語であり、CSS(CSSプリプロセッサを含む)よりもはるかに強力です。これらの種類の内部DSLを優先するか外部DSLを優先するかによって異なります。好みの問題。」私はこれらの2つのシナリオについて話していました。

1:

/** @jsx React.DOM */
var colored = {
  color: myColor
};
React.renderComponent(<div style={colored}>Hello World!</div>, mountNode);

二:

// SASS:
.colored {
  color: $my-color;
}
// HTML:
<div class="colored">Hello World!</div>

最初の例では、「JavaScriptでCSSを記述します。きれいではありません。」という質問で説明したものを使用します。2番目の例では、Sassを使用しています。JavaScriptを使用してCSSを記述することは(「かなり」の定義によっては)きれいではないかもしれませんが、それを行うことには1つの利点があります。

Sassで変数と関数を使用できますが、それらはレキシカルスコープまたはダイナミックスコープですか?それらは静的または動的に入力されますか?強くまたは弱く?数値型はどうですか?型強制?どの値が真実であり、どれが偽であるか?高階関数を使用できますか?再帰?テールコール?レキシカルクロージャー?通常の順序で評価されますか、それとも適用可能な順序で評価されますか?遅延評価または熱心な評価はありますか?関数への引数は、値または参照によって渡されますか?それらは変更可能ですか?不変?持続的?オブジェクトはどうですか?クラス?プロトタイプ?継承?

これらは些細な質問ではありませんが、Sass or Lessコードを理解したい場合は、それらに対する答えを知る必要があります。JavaScriptに対するそれらの回答は既に知っているので、それらのレベルでのすべての内部DSL(Reactのインラインスタイルなど)を既に理解しているので、Reactを使用する場合、それらに対する回答のセットを1つだけ知っている必要があります)質問、たとえば、SassとHandlebarsの場合、これらの答えの3つのセットを知り、その意味を理解する必要があります。

どちらかの方法が常に優れていると言うわけではありませんが、ミックスに別の言語を導入するたびに、一見すると明らかではないかもしれない価格を支払います。この価格は複雑です。

元々の意味を少し明確にしたいと思います。

データバインディング

双方向バインディング

これは本当に興味深いテーマであり、実際には好みの問題でもあります。双方向が常に一方向より優れているとは限りません。アプリケーションの可変状態をどのようにモデル化するのかという問題です。私は常に双方向バインディングを関数型プログラミングの原理に多少反するアイデアと考えていましたが、関数型プログラミングだけが機能するパラダイムではなく、一部の人々はこの種の動作を好み、両方のアプローチは実際にはかなりうまくいくようです。あなたは、見て反応における状態のモデリングに関する設計上の決定の内容に興味があるならピート・ハントで話を(質問ににリンクされている)とトムOcchinoとヨルダンWalkeによって話  に非常によくそれを説明します私の意見。

更新: Pete Huntによる別の講演も参照してください:予測できない、正しくない:機能的なDOMプログラミング

アップデート2:多くの開発者が双方向データフロー、または双方向バインディングに反対していることを指摘する価値があります。FVCアプリケーションアーキテクチャを例に挙げて、MVCモデルを明示的に回避し(大規模なFacebookおよびInstagramアプリケーションではスケーリングが困難であることが判明した)、厳密に単方向のデータフローを優先します(Hacker Way:Rethinking Web App Development at Facebook talkを参照) Tom Occhino、Jing Chen、Pete Huntの優れた紹介)また、AngularJSに対する多くの批判 (双方向データバインディングで知られる、MVCモデルに大まかに基づいた最も人気のあるWebフレームワーク)には、その双方向データフローに対する引数が含まれています。

アップデート3:きれいに上記disscussedの問題のいくつかがされて説明するもう一つの興味深い記事ReactJSのフラックスを解体- ReactJSでMVCを使用していないミカエルBrassman、の著者によってRefluxJS(フラックスに触発された単方向のデータフローアプリケーションアーキテクチャのためのシンプルなライブラリ)。

更新4: Ember.jsは現在、双方向のデータバインディングを廃止し、将来のバージョンではデフォルトで一方向になります。参照:2014年11月15日にトロントで開催されたEmbergarten SymposiumのStefan PennerによるThe Future of Emberの講演。

更新5:参照:Ember 2.0 RFCへの道-Tom Daleによるプル要求での興味深い議論

「元のテンプレートレイヤーを設計したとき、すべてのデータバインディングを双方向に作成することはそれほど有害ではないと考えました。双方向のバインディングを設定しないと、事実上一方向のバインディングになります。

その後、(Reactの友人の助けを借りて)コンポーネントが、気まぐれな突然変異に気を配ることなく、子供たちにデータを配布できることを望んでいることに気付きました。

さらに、コンポーネント間の通信は、通常、イベントまたはコールバックとして最も自然に表現されます。これはEmberで可能ですが、双方向のデータバインディングの優位性により、多くの場合、双方向のバインディングを通信チャネルとして使用する経路に人々を導きます。経験豊富なEmber開発者は(通常)この間違いを犯しませんが、簡単に犯すことができます。」 [強調を追加]

ネイティブとVM

ネイティブブラウザサポート(「より高速であることが保証されている」を参照)

最後に、意見の問題ではない何か。

実際、ここではまったく逆です。もちろん「ネイティブ」コードはC ++で記述できますが、JavaScriptエンジンは何で記述されていると思いますか?

実際のところ、JavaScriptエンジンは、今日使用している最適化において本当に驚くべきものです。V8だけでなく、SpiderMonkey、さらにChakraさえも最近輝いています。また、JITコンパイラーでは、コードはできるだけネイティブであるだけでなく、静的にコンパイルされたコードでは実行できない、実行時の最適化の機会もあることに留意してください。

JavaScriptが遅いと人々が考えるとき、それらは通常DOMにアクセスするJavaScriptを意味します。DOMは遅いです。それはネイティブで、C ++で書かれていますが、実装しなければならない複雑さのために非常に遅いです。

コンソールを開き、次のように記述します。

console.dir(document.createElement('div'));

divDOMにアタッチされていない空の要素が実装する必要があるプロパティの数を確認します。これらは、 「独自のプロパティ」である最初のレベルのプロパティです。プロトタイプチェーンから継承されない:

align、onwaiting、onvolumechange、ontimeupdate、onsuspend、onsubmit、onstalled、onshow、onselect、onseeking、onseeked、onscroll、onresize、onreset、onratechange、onprogress、onplaying、onplay、onpause、onmousewheel、onmouseup、onmouseover、onmouseout、onmousemove、onmouseove、onmousemove、onmouseove、onmousemove、onmouse onmouseenter、onmousedown、onloadstart、onloadedmetadata、onloadeddata、onload、onkeyup、onkeypress、onkeydown、oninvalid、oninput、onfocus、onerror、onended、onemptied、ondurationchange、ondrop、ondragstart、ondragover、ondragleave、ondragenter、ondragend、ondragend oncontextmenu、onclose、onclick、onchange、oncanplaythrough、oncanplay、oncancel、onblur、onabort、spellcheck、isContentEditable、contentEditable、outerText、innerText、accessKey、hidden、webkitdropzone、draggable、tabIndex、dir、translate、lang、title、childElementCount、lastElementChild、firstElementChild、children、nextElementSibling、previousElementSibling、onwheel、onwebkitfullscreenerror、onwebkitfullscreenchange、onselectstart、onsearch、onpaste、oncut、oncopy、onbeforepaste、onbeforecut、onbeforecopy、webkitShadowRoot、dataset、classList、className、outerHTML、innerHTML、scrollHeight、scrollWidth、scrollLeft、scrollLeft、scrollLeft clientHeight、clientWidth、clientTop、clientLeft、offsetParent、offsetHeight、offsetWidth、offsetTop、offsetLeft、localName、prefix、namespaceURI、id、style、attributes、tagName、parentElement、textContent、baseURI、ownerDocument、nextSibling、previousSibling、lastChild、firstChild、childNodes、 parentNode、nodeType、nodeValue、nodeNameoncopy、onbeforepaste、onbeforecut、onbeforecopy、webkitShadowRoot、dataset、classList、className、outerHTML、innerHTML、scrollHeight、scrollWidth、scrollTop、scrollLeft、clientHeight、clientWidth、clientTop、clientLeft、offsetParent、offsetHeight、offsetWidth、offsetTop、offsetLeft、localName、prefix、 namespaceURI、id、スタイル、属性、tagName、parentElement、textContent、baseURI、ownerDocument、nextSibling、previousSibling、lastChild、firstChild、childNodes、parentNode、nodeType、nodeValue、nodeNameoncopy、onbeforepaste、onbeforecut、onbeforecopy、webkitShadowRoot、dataset、classList、className、outerHTML、innerHTML、scrollHeight、scrollWidth、scrollTop、scrollLeft、clientHeight、clientWidth、clientTop、clientLeft、offsetParent、offsetHeight、offsetWidth、offsetTop、offsetLeft、localName、prefix、 namespaceURI、id、スタイル、属性、tagName、parentElement、textContent、baseURI、ownerDocument、nextSibling、previousSibling、lastChild、firstChild、childNodes、parentNode、nodeType、nodeValue、nodeNameparentElement、textContent、baseURI、ownerDocument、nextSibling、previousSibling、lastChild、firstChild、childNodes、parentNode、nodeType、nodeValue、nodeNameparentElement、textContent、baseURI、ownerDocument、nextSibling、previousSibling、lastChild、firstChild、childNodes、parentNode、nodeType、nodeValue、nodeName

それらの多くは実際にはネストされたオブジェクトです- divブラウザで空のネイティブの第2レベル(独自の)プロパティを確認するには、このフィドルを参照してください。

私は真剣に、すべての単一divノードのonvolumechangeプロパティを意味しますか?それは間違いですか?いや、それは「イベントハンドラの1つだけのレガシーDOMレベル0の伝統的なイベントモデルのバージョンだしなければなりませんサポートされ、すべてのHTML要素での[強調追加]の両方のコンテンツの属性として、およびIDL属性」セクション6.1.6.2 HTMLの仕様のW3Cによる-それを回避する方法はありません。

一方、これらはdivReactのフェイクDOMの最初のレベルのプロパティです:

props、_owner、_lifeCycleState、_pendingProps、_pendingCallbacks、_pendingOwner

まったく違いますよね?実際、これはJSON(LIVE DEMO)にシリアル化されたオブジェクト全体です。これは、 循環参照を含まないため実際にJSONにシリアル化できるためです-ネイティブDOMの世界では考えられないことです):

{
  "props": {},
  "_owner": null,
  "_lifeCycleState": "UNMOUNTED",
  "_pendingProps": null,
  "_pendingCallbacks": null,
  "_pendingOwner": null
}

これが、ReactがネイティブブラウザーのDOMよりも高速になる主な理由です。この混乱を実装する必要がないためです。

参照してくださいスティーブンLuscherことで、このプレゼンテーションでは、 C ++で書かれたネイティブDOMまたはJavaScriptで書かれた偽のDOM:速いがあるかを確認します。とても公平で楽しいプレゼンテーションです。

更新: 将来のバージョンのEmber.jsは、パフォーマンスを向上させるために、Reactに大きく影響された仮想DOMを使用します。参照:2014年11月15日にトロントで開催されたEmbergarten SymposiumのStefan PennerによるThe Future of Emberの講演。

要約すると、テンプレート、データバインディング、カスタム要素などのWebコンポーネントの機能には、Reactよりも多くの利点がありますが、ドキュメントオブジェクトモデル自体が大幅に簡素化されるまで、パフォーマンスはそれらの1つではありません。

更新

この回答を投稿してから2か月後に、関連するニュースがいくつかありました。私はちょうどTwitterで書かれている、の最新のバージョンのAtom JavaScriptでのGitHubによって書かれたテキストエディタには、Facebookの、より良いパフォーマンスを得るために反応使用していても、ウィキペディアによると、それは完全にコントロールを持っているので、「アトムはクロムに基づくものであり、C ++で書かれました」ネイティブC ++ DOM実装(参照アトムの核をし、 独自のWebブラウザが付属しているため、Webコンポーネントのサポートが保証されています。これは、Webアプリケーションでは通常利用できない他の種類の最適化を使用できた現実世界のプロジェクトのごく最近の例であり、Atomにもかかわらず、最高のパフォーマンスを達成するためにJavaScriptで記述されたReactを使用することを選択しましたそもそもReactで構築されていなかったので、それを行うのは簡単な変更ではありませんでした。

更新2

Todd ParkerがWebPagetestを使用して、Angular、Backbone、Ember、Polymer、CanJS、YUI、Knockout、React、およびShoestringで記述されたTodoMVCサンプルのパフォーマンスを比較する興味深い比較があります。これは、これまで見てきた中で最も客観的な比較です。ここで重要なことは、それぞれの例はすべてこれらのフレームワークの専門家によって書かれたものであり、すべてGitHub利用可能であり、コードの一部を最適化して高速に実行できると考えている人が改善できることです。

アップデート3

将来のバージョンのEmber.jsには、ここで説明する多くのReactの機能(仮想DOMや一方向データバインディングなど)が含まれます。これは、Reactで生まれたアイデアが既に他のフレームワークに移行していることを意味します。参照:The Road to Ember 2.0 RFC-Tom Daleによるプルリクエストでの興味深い議論(開始日:2014-12-03):「Ember 2.0では、「仮想DOM」を採用し、データフローモデルを採用しますReactの最高のアイデアであり、コンポーネント間のコミュニケーションを簡素化します。」

同様に、Angular.js 2.0はここで説明した概念の多くを実装しています。

更新4

Igwe Kaluによるこのコメントに答えるために、いくつかの問題について詳しく説明する必要があります。

「React(JSXまたはコンパイル出力)を単純なJavaScriptと比較することは賢明ではありません。Reactが最終的に単純なJavaScriptに還元される場合。便利さ以外に問題の機能を検討する場合、特別な利点は追加されません。」(ここに完全なコメント)

十分に明確ではなかった場合、私の答えの一部として、ネイティブDOM(ブラウザーのホストオブジェクトとして実装)とReactの偽/仮想DOM(JavaScriptで実装)で直接操作するパフォーマンスを比較しています。私が作るしようとしていた点は、JavaScriptで実装された仮想DOMがあることであることができ、実際のC ++で実装DOMとアウトパフォームしませリアクト(それがあるため、明らかにあまり意味がありませんJavaScriptをアウトパフォームすることができますされて JavaScriptで記述されたが)。私のポイントは、「ネイティブ」C ++コードが「非ネイティブ」JavaScriptよりも高速であるとは限らないことです。Reactを使用してそのポイントを説明するのは単なる例です。

しかし、このコメントは興味深い問題に触れました。ある意味、フレームワーク(React、Angular、jQuery)が何らかの理由(パフォーマンス、移植性、機能など)で必要ないことは事実です。つまり、コストを正当化できます。

しかし-デイブスミスはきれいにそれを置くとして、Webフレームワークのパフォーマンスを比較するときのポイントを欠場する方法:「2つのWebフレームワークを比較すると、問題がないことができ、私のアプリは、フレームワークXと高速での質問はあります私のアプリは、フレームワークと高速でありますバツ。"

私の2011年の答え:jQueryのを使用しないように、いくつかの実証的、技術的な理由は何私はjQueryのようなライブラリせずにポータブルDOM-操作コードを記述することは不可能ではないことが、人々はほとんどそうしないことを、同様の問題を説明します。

プログラミング言語、ライブラリ、またはフレームワークを使用するとき、人々は物事を行うのに最も便利で慣用的な方法を使用する傾向があり、完璧ではなく不便な方法を使用します。優れたフレームワークの真の価値は、そうでなければ困難なことを簡単にすることであり、秘密は正しいことを便利にすることです。その結果、ラムダ計算の最も単純な形式または最も原始的なチューリングマシンとまったく同じ能力を自由に使用できますが、特定の概念の相対的な表現力は、それらの概念がより簡単に、またはまったく表現される傾向があることを意味し、適切なソリューションは単に可能であるだけでなく、実際に広く実装されています。

更新5

React + Performance =?2015年7月のPaul Lewisの記事は、ReactがFlickrの写真の無限リスト用に手書きで書かれたバニラJavaScriptよりも遅い例を示しています。これはモバイルで特に重要です。この例は、特定のユースケースと特定のターゲットプラットフォームおよびデバイスのパフォーマンスを誰もが常にテストする必要があることを示しています。

おかげケビンLozandierのための私の注意にそれを持って来ます


75
それが包括的な答えです、ありがとう!
デムヴンツ

14
AtomはReactから離れつつあるようです。github.com/atom/atom/issues/3677を参照してください。
ジュホVepsäläinen14年

6
@ash:スレッドをさらに読むと、最終的にReactや他のフレームワークから完全に離れて、カスタム要素とシャドウDOMを使用して独自にロールバックする方法について話します。
musicfreak 14

3
上記の文言を明確にするために、@ ErikAllikのリストでは、FRP(Functional Reactive Programming)は新しい言語ではなく、人気を集めているアプローチです。実際には、(elm-lang.orgから)「エルムは、官能性反応プログラミングの考えに基づいている」、と彼は述べたように、ハスケル、などのためのFRPフレームワークがある
ジョン・クームス

5
tl;とにかく読む-素晴らしい、詳細な答え!
マークKコーワン

16

ポリマーは素晴らしいです。Reactは素晴らしいです。それらは同じものではありません。

Polymerは、下位互換性のあるWebコンポーネントを構築するためのライブラリです。

ReactはMVCのVです。それはビューであり、他には何もありません。少なくともそれ自体ではありません。

Reactはフレームワークではありません。

React + Flux + Node +(GulpまたはGrunt)はフレームワークに匹敵しますが、これらのうち3つは反応の一部ではありません。

開発者が反応するテクノロジー、パターン、およびアーキテクチャスタイルは多数ありますが、反応自体はフレームワークではありません。

誰も比較するべきではない、最も簡単なことを言うのに時間をかけなかったことは悲しいです。これらには重複部分がありますが、同じものよりも異なります。

どちらもWebコンポーネントを定義できますが、方法は異なります。それ以外は非常に異なるツールです。


データ状態を保持および更新し、コンポーネントを介してhtmlのフラグメントをレンダリングするため、ReactはVだけでなくMとVの両方ではありませんか?
abelito

1
fluxやreduxのような反応状態管理ライブラリがありますが、これらは反応にパッケージ化されていません。
ロボット寿司

なるほど、Viewデータはサーバー側に送信されるまでモデルデータとは見なされません。Reactはコンポーネントの状態(ビューデータ)を保持しますが、送信するまでビューデータのままです。それは理にかなっている。
アベリト

15

Reactの連中は、ReactとWebコンポーネントの比較についてかなり良い説明をしています:

ReactとWebComponentsを比較して対比しようとすると、2つのライブラリが異なる問題を解決するために構築されるため、必然的に驚くべき結論に至ります。WebComponentsは再利用可能なコンポーネントの強力なカプセル化を提供し、ReactはDOMとデータの同期を保つ宣言型ライブラリを提供します。2つの目標は相補的です。エンジニアはテクノロジーを組み合わせて使用​​できます。開発者として、WebComponentsでReactを使用するか、ReactでWebComponentsを使用するか、またはその両方を自由に行えます。


14

1つのポイントで具体的に別の答え:

JavaScriptをバニラJavaScriptで記述し、CSSでCSSを記述し、HTMLでHTMLを記述します。

CoffeeScript、TypeScript、ClojureScriptなどでJavascriptを記述することを妨げるものは何もありません。それは純粋に好みの問題です。

HTMLは、静的 HTMLドキュメントに最適なDSLです。ただし、ダイナミックHTMLには何も提供しません。また、ブラウザでは、HTMLを動的にするのに最適な言語はJavascriptであり、アドホックなJavaScript DOM操作を備えた純粋なHTMLや、ハンドル言語のような半言語ではないテンプレート言語ではありません。

CSSの場合、CSSが静的な場合は、通常どおりに記述します。いくつかのランタイム値に基づいて動的にする必要がある場合、HTMLと同じ話になります。Javascriptを動的にする最良の方法です。


1
私は答えに感謝しますが、それは実際には私のポイントではありませんでした。うまくいけば、私の編集によって質問が少し明確になりましたか?
CletusW 14年

1
ごめんなさい。別のファイルに任意のスタイル言語でスタイルを書くことができます。また、ReactのJSXにより、マークアップ言語を使用しているように見えます。
DjebbZ

3
「Javascriptは[CSS]を動的にする最良の方法です」-単にそれが実際に理由を説明していないと言っているだけです。
ピラウ14年

1
まあ、ユーザーの入力やビジネスルールに応じてスタイル/クラスを変更する必要がある場合は、JavaScriptを使用して変更してください。バニラjsでは、DOMノードのclassListまたはstylesプロパティを操作します。Reactを使用すると、仮想DOMを操作する同じ目標を達成できます。より明確ですか?
DjebbZ

2
ReactのコアコントリビューターであるVjeuxは最近、Reactを使用して「CSS in JS」コンセプトを推進する講演を行いました。:私は、あなたはそれが何であるか見て喜んであり、それは面白いことだと思うblog.vjeux.com/2014/javascript/react-css-in-js-nationjs.html
DjebbZ

6

Webコンポーネントは使用していませんが、イベントハンドラーに手動でコード化された変換ロジックを追加する必要があるようです。

Polymerの例のスニペット:

 <script>
   Polymer({
     counterChanged: function() {
       this.$.counterVal.classList.add('highlight');
     },
 ...

Reactの重要なポイントは、突然変異ロジックを排除することで複雑さを軽減することです。代わりに、仮想DOMを単純に再生成し、Reactのdiffアルゴリズムに実際のDOMで何を変更する必要があるかを判断させます。


5
その例をどこで手に入れたかはわかりませんが、Polymerは、クラス名を含め、データバインディングを優先して手動のDOM突然変異を推奨していません。
CletusW 14

これは、polymer-project.orgのフロントページにある「要素の作成」タブの例です。
リムスコーダー14

4
うわー、あなたは正しい!彼らは単に自動ノード検索の例を望んでいたと思います。ただし、これはおそらく最良の方法ではありません。
CletusW 14

6

私の意見では、Reactの最大の欠点は、Web標準に基づいていないことです。現在、Reactは非常に強力なツールですが、可能な限りブラウザーが提供するものの多くを回避しているため、今では理にかなっていると思われる決定は、ブラウザーの組み込み機能が続くため、数年後には意味をなさない可能性があります改善します。それで、私はそれについて、そしてそれがウェブアプリケーションのいくつかの異なる側面にどのように影響するかについて話したいです。

性能

Reactの利点は、DOMとイベントモデル全体を完全に再発明することであり、既存の標準DOMは重くて高価であり、そうでないことを主張したいのですが、結局のところ、私はパフォーマンスを見つけられませんでしたよく書かれたBackboneまたはPolymerアプリケーションから得られるものよりも優れた反応を示します。実際、私の専門的な経験のほとんどで、Reactのパフォーマンスは実際には少し悪くなっています。それは、Reactが遅いということではありません...それは、私たちがそれを手に入れる前に考えていた最先端のパフォーマンス選択ではありません。

rspの答えで、彼はdivに対するReactのDOMモデルはネイティブDOM divよりもはるかに軽量であり、それが確かに正しいと指摘します。ただし、Reactが役立つためには、その「仮想」divが何らかの時点で実際のdivになる必要があります。私の世界観では、React divとネイティブdivの問題ではありません。React div +ネイティブdiv対ネイティブdivです。ReactのDOMバージョンのオーバーヘッドは些細なものではありません。標準がこれらの不要な属性の一部をドロップし、ネイティブDOMノードをより軽くできるようにすると、突然そのオーバーヘッドは本当に高価になります。

私の以前の勤務先の1つでは、Polymerにいくつかのアプリケーションがあり、Reactにいくつかのアプリケーションがありました。初期のPolymerアプリケーションの1つは、Reactで書き直されました。これは、それが会社の標準であり、測定に基づいて、この同じアプリケーションのReactバージョンを、Polymerバージョンより約30%多くのメモリを使用して巻き取ったためです、差はわずかでしたが、Polymerバージョンも同様に短時間でレンダリングされました。ここで考慮すべきことの1つは、私たちが人々によって書かれたアプリケーションについて話していることであり、人々は完璧ではないため、このアプリケーションのReact実装がReactのすべてを活用していない可能性があります。しかし、少なくとも一部は、Reactが独自のバージョンのDOMを持っているために発生するオーバーヘッドに関係していると思います。

Reactは独自のモデルを使用してDOM全体を再発明し、それを主要なパフォーマンス最適化に使用します。ビューは仮想DOMにレンダリングされ、実際のDOMに投影されます。変更があり、ビューを更新する必要がある場合、ビューは新たに仮想DOMに再レンダリングされ、そのツリーは以前のツリーと比較されて、この変更を反映するために実際のDOMで変更する必要があるノードが決定されますビューで。これは効率的なDOM更新を行うための非常に賢いアプローチですが、これらすべての仮想DOMツリーを維持し、それらを比較して実際のDOMで何を変更するかを決定するのはオーバーヘッドです。現時点では、このオーバーヘッドはパフォーマンス上のメリットによって大幅に相殺されていますが、ネイティブDOMが時間とともに改善されるにつれて、スケールは他の方向にシフトします。Reactアプリがどのように老化するか心配です。そして3年後には、DOMをより直接的に扱うものよりもはるかに遅くなります。この仮想DOMアプローチはちょっとしたハンマーであり、Polymerのような他のライブラリは、DOMをより微妙な方法で扱うための非常に効率的なアプローチを実装することができました。

パフォーマンスの更新: しばらくつまずいたライブラリの1つは、DOMの更新を管理するより良い仕事だと思うことをします。これはGoogleのIncremental Domライブラリであり、domをその場で動作させ、「仮想コピー」を作成する必要がないという事実は、はるかにクリーンなアプローチであり、メモリのオーバーヘッドははるかに少ないと思います。詳細はこちら:http : //google.github.io/incremental-dom/#about

宣言的コンポーネントと命令的コンポーネント

アプリケーションのコンポーネント化について話しているときによく耳にするものの1つは、コンポーネントが宣言的であることのすべての利点です。Reactの世界観の中では、すべてが素晴らしく、宣言的です。マークアップを返すJavaScriptを記述し、Reactがそれをすべて結び付けます。そして、Reactのみを使用するまったく新しいアプリケーションを扱っている場合、それは素晴らしいことです。いくつかのコンポーネントを記述できます。Reactが所有するDOM内にいる限り、そのタグをページに配置してコンポーネントを消費するのと同じくらい簡単です。

しかし、これらのコンポーネントを取り出してReactの外部で使用するとすぐに、事態は非常に面倒になります。Reactコンポーネントをタグに作成する方法は、Web標準が提供するものとは完全に異なるため、これらのコンポーネントを宣言的な方法で使用する方法をReact以外に知っている人はいません。Handlebarsテンプレートを使用している既存のBackboneビューにReactコンポーネントを配置する場合は、ハンドルとして使用できるクラスまたはIDを使用してテンプレートのダミーdivをレンダリングし、命令型JavaScriptを記述してそのダミーdivを見つけてマウントする必要がありますそれにあなたのコンポーネント。サーバー側テンプレートを使用しているExpress.jsアプリケーションを取得しましたか?まあ、それは同じ歌とダンスです。JSPページ?あなたは笑いますが、まだそれらを使用しているアプリケーションがたくさんあります。既存のコードのないある種のスタートアップでない限り、多くのアプリケーションでReactコンポーネントを再利用するために、配管を書く必要があります。一方、PolymerはWebコンポーネント標準を介してコンポーネントを実現し、Custom Element仕様を使用することで、Polymerはブラウザがネイティブに消費方法を知っているコンポーネントを作成できます。Polymerコンポーネントを、JSPページ、Express.jsテンプレート、ASP.NETビュー、バックボーンビューなど、Reactコンポーネントの内部に配置できます。文字通り、HTMLを使用できる場所ならどこでも、Polymerコンポーネントを使用できます。再利用のためにエンジニアリングを行っている人々は、Web標準に目を向けています。なぜなら、標準は、物事を互いに互換性を持たせることを容易にする契約だからです。YouTubeは、Polymerでますます多くのものを作成し続けています(出典:Polymerは、Webコンポーネント標準を通じてコン​​ポーネントを実現します。Polymerは、カスタム要素仕様を使用することで、ブラウザーがネイティブに使用方法を知っているコンポーネントを作成できます。Polymerコンポーネントを、JSPページ、Express.jsテンプレート、ASP.NETビュー、バックボーンビューなど、Reactコンポーネントの内部に配置できます。文字通り、HTMLを使用できる場所ならどこでも、Polymerコンポーネントを使用できます。再利用のためにエンジニアリングを行っている人々は、Web標準に目を向けています。なぜなら、標準は、物事を互いに互換性を持たせることを容易にする契約だからです。YouTubeは、Polymerでますます多くのものを作成し続けています(出典:Polymerは、Webコンポーネント標準を通じてコン​​ポーネントを実現します。Polymerは、カスタム要素仕様を使用することで、ブラウザーがネイティブに使用方法を知っているコンポーネントを作成できます。Polymerコンポーネントを、JSPページ、Express.jsテンプレート、ASP.NETビュー、バックボーンビューなど、Reactコンポーネントの内部に配置できます。文字通り、HTMLを使用できる場所ならどこでも、Polymerコンポーネントを使用できます。再利用のためにエンジニアリングを行っている人々は、Web標準に目を向けています。なぜなら、標準は、物事を互いに互換性を持たせることを容易にする契約だからです。YouTubeは、Polymerでますます多くのものを作成し続けています(出典:Polymerコンポーネントを、JSPページ、Express.jsテンプレート、ASP.NETビュー、バックボーンビューなど、Reactコンポーネントの内部に配置できます。文字通り、HTMLを使用できる場所ならどこでも、Polymerコンポーネントを使用できます。再利用のためにエンジニアリングを行っている人々は、Web標準に目を向けています。なぜなら、標準は、物事を互いに互換性を持たせることを容易にする契約だからです。YouTubeは、Polymerでますます多くのものを作成し続けています(出典:Polymerコンポーネントを、JSPページ、Express.jsテンプレート、ASP.NETビュー、バックボーンビューなど、Reactコンポーネントの内部に配置できます。文字通り、HTMLを使用できる場所ならどこでも、Polymerコンポーネントを使用できます。再利用のためにエンジニアリングを行っている人々は、Web標準に目を向けています。なぜなら、標準は、物事を互いに互換性を持たせることを容易にする契約だからです。YouTubeは、Polymerでますます多くのものを作成し続けています(出典:http://react-etc.net/entry/youtube-is-being-rebuilt-on-web-components-and-polymer)、Polymerの標準ベースの側面が理由であるとしか想像できません。YouTubeページの中央にあるYouTubeプレーヤーは、コンテンツソースをプロパティとして取り込むコンポーネントになり、YouTubeプレーヤーをページに埋め込みたい人は誰でも、YouTubeが使用しているものとまったく同じプレーヤーコードを文字通り使用できます、そして彼らは単に彼らのページにタグを貼り付けることによってそうすることができます。

概要

Reactの魅力的な側面があることは確かです。使用しているのがReactのみである場合は、いくつかのウィジェットとコンポーネントを作成し、それらを宣言的に再利用できます。しかし、Reactは、すべての同期を維持するためにブラウザー内にブラウザーと複雑なメカニズムを構築するのではなく、Webコンポーネントの標準の一部を使用して何を達成するのであれば、Reactの方がはるかに良かったと思います。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.