Angular 2 vs React:究極のダンスオフ

サンセットブレイク—AlíMarín(CC BY-NC-ND 2.0)

私をフォローしているほとんどの人は、私が個人的にReactを好んでいることを知っていますが、もちろん、情報に基づかないバイアスに基づいてではなく、自分の決定を教育することが好きです。最近、Angular 2を詳細に調査しています。私の意見では、これがReactと比較されます。

注:時々、Angular 2「ng2」と略されます。これは、コミュニティで一般的な慣行です。

踊りましょう

開発者の経験に集中したいので、開発者がそれぞれng2とReactの使用についてどのように感じているかを見てみましょう。 Angular 2とReactの両方について、フォロワーに「もう一度使用しますか?」

再びAngular 2を使用すると答えたのは17%だけでした。

56%は、Reactを再び使用すると答えました。

それでおしまい。ゲームオーバー。右?まあ、そうではありません。ほとんどの回答者はまだAngular 2を使用していなかったため、これを公平にするために、投票からそのグループを削除する必要があります。

まだ使用していないグループを削除すると、両方のスコアが良くなります:

反応:84%

角度2:38%

Reactは明らかに顧客満足度調査で勝利します。しかし、これは科学的ではありません。これは私のフォロワーであり、投票をリツイートした人々のフォロワーであり、主にReactについて話しますが、これらは実際の経験を共有している実際のユーザーであるため、数字はまったく同じではないと言っても安全だと思います一般的なユーザー集団全体で、彼らは私たちに何を期待するかについての良いアイデアを与えてくれます。

違いと、人々が自分のやり方を感じる理由を詳しく見てみましょう。

性能

多くの人々は、技術の選択はすべてパフォーマンスを重視すべきだと考えています。 React対Angular 1の記事はパフォーマンスに集中する傾向がありました(Angular 1のダーティチェックとダイジェストサイクルにより、Reactは簡単に勝ちました)。しかし、Angular 2はその動作をクリーンアップしました。これは速い。 ReactとAngular 2の両方のテストでは、パフォーマンスも大きな問題ではありませんでした。それらにはそれぞれ警告がありますが、私はそれらに深く入りません。

他のすべてのCSパフォーマンスの問題と同様に、高価な操作を何度も繰り返す必要がある場合、アプリの速度が低下します。 Reactとng2についても同様です。つまり、可能な場合はDOMの更新を避け、可能な場合は深い状態の繰り返しを避け、オブジェクトやコンポーネントの過剰な作成/破棄などを避けます。この記事の目的のために、 「2台のスーパーカーを比較していますが、どちらもスピードデーモンです。あなたのマイレージは異なる場合があります。

そうは言っても、私はチームのパフォーマンスをアプリのパフォーマンスと同様に高く評価しています。この比較は、開発者の経験と開発者チームのパフォーマンスの問題に集中します。最終的に、あなたのチームは素早く動き、素早く変更できる必要があります。これらの各ツールがこれらの面でどのように比較されるかを探ります。

Angular 1がフロントエンドをどのように変換したか

Angular 1は、Backbone、Knockout、および新しいWebコンポーネント仕様のアイデアを組み合わせ、ng1カスタムディレクティブを介してカスタムコンポーネントを大衆にもたらしました。また、OOPからの一般的なパターン:依存性注入コンテナーをもたらしました。

これは明らかなはずですが、Angular 1が普及させた最も変革的なIMOはカスタムコンポーネントでした。現在、一般的なフロントエンドフレームワークはすべてカスタムコンポーネントをサポートしています。

Reactがフロントエンドをどのように変えたか

Reactがリリースされたとき、MV *と2方向のデータバインディングは嵐によってフロントエンドを奪っていました。バックボーンとノックアウトはヘビーヒッターでした。 Angular 1はブロックの新しい子供でした。

Reactにはモデルの組み込みコンセプトが付属していなかったため、チームはFluxアーキテクチャと一緒に使用することを推奨しました。 Fluxは、単方向のデータフローとトランザクション状態を規定するUIアーキテクチャです。 「Reduxアーキテクチャを改善するための10のヒント」で、両方の利点について詳しく説明しました。 React、Flux、およびReduxに慣れていない場合は、この記事を続ける前に読むことを強くお勧めします。

Reactは、MVCを独力で時代遅れの技術のように見せ、大衆に対する一方向の流れを解き放つようにしたため、変革的でした。

私の意見では、これはHTMLとJavaScript以来のフロントエンドアーキテクチャの最も重要な変換です。

幸いなことに、それは非常に変革的であり、Reactに固有のものではなくなりました。 ng2でも同様に達成できます。

Reactで見つからないAngular 2の内容

もちろん、どちらのフレームワークもカスタムコンポーネントの構築をサポートしています。 Angular 2には、内部にいくつかの余分なものがありますが、本質的には両方とも、アプリケーションスタックのフロントエンドでUIを構築するために存在します。 Angular 2には、より多くの処方箋と「バッテリーを含む」という哲学があります。

Angular 2の処方箋を見てみましょう。

TypeScript

TypeScriptとの間に愛と憎しみの関係があります。私のお気に入りの1つは、TypeScriptがあらゆる種類のバグからアプリを保護するという一般的なアイデアです。悪いニュースがあります:ありません。

「静的型に関する衝撃的な秘密」をお読みください。バグの削減は、静的型が得意とするものではありません。

型の正確性は、プログラムの正確性を保証するものではありません。
  • 静的型では捕捉できない多くのバグがあります。
  • バグ(TDD、コードレビュー)をキャッチする客観的に優れた方法があり、それらはほとんどのタイプエラーをキャッチします。

結果?静的型は1つのクラスのバグを排除できることは事実ですが、コードの複雑さが増すという犠牲を払っており、プロジェクトに対する全体的なバグ削減の影響はわずかです。

静的型は、主に開発者ツールに最適です。コードを作成する際に、関数呼び出しの署名など​​についてのインラインドキュメントを入手できると非常に便利です。しかし、それを実現するためにどこでもインラインアノテーションが常に必要なわけではありません。

明確さ、開発者向けドキュメント、および開発者向けツールの強化のために必要な場合に型注釈を指定するというアイデアは大好きですが、ほとんどの場合、型推論を強く好みます。インライン型宣言は、コードを乱雑にし、読みにくくする傾向があります。

良いニュースは、TypeScriptが型推論に非常に優れていることです。必要に応じて、ほとんどの場合、推論に依存できます。その推論機能はTernよりも優れているように見え、AtomおよびMicrosoft Codeの開発者ツールは、同等のTernプラグインよりもはるかに優れています。実際、TypeScriptは、今日のJavaScriptの世界で利用可能な最高のインテリセンス開発者エクスペリエンスを提供していると言っているところまで行きます。あなたはそれに恋するかもしれません。

TypeScriptは、今日のJavaScriptの世界で利用可能な最高のインテリセンス開発者エクスペリエンスを提供します。

型推論機能のために厳密にTypeScriptを使用し、宣言されていないモジュールとあいまいなパラメーターに対してエラーの発生をスキップできる場合に限り、通常のJavaScriptファイルで常に使用します。簡単な選択。

構成が0の慣例により、タイプアノテーションのみが常に別のファイル(明確にタイプされた `d.ts`ファイルなど)に常駐している場合は、より多くのアノテーションも使用し、TypeScriptをさらに多く使用したいと思います。 TypeScriptは文字通り「単なるJavaScript」であるため、TypeScriptを任意のワークフローと簡単に統合できます。標準のJavaScriptをサポートする任意のコンパイラでコンパイルできます。

実際には、TypeScriptは、設定のオーバーヘッド(モジュールのインポートエラーを防ぐためにすべてのライブラリの入力を追跡する)、構文のオーバーヘッド(通常はインラインで宣言される)、多くの「任意の」エスケープハッチ、等…

「任意の」エスケープハッチを明確にするために、TypeScriptは型コンストラクタースタイルの構文を使用してジェネリックをサポートしますが、関数型プログラミングスタイルの構造、オブザーバブル、高次関数の切り替えなどを使用して動作させるのは常に明確または簡単ではありません...

正しいタイプの入力方法を見つけるのではなく、開発者は一般的に「any」を使用します。型チェックをあきらめて、「どんな型でもここで機能します」と言ったのと本質的に同じことですが、それは厳密には真実ではありません。

オーバーヘッドおよびエスケープハッチはすべて、バグを隠すためのより多くの表面積を追加します。チームによって無視されたばかりのTypeScriptエラーがあるTypeScriptプロジェクトがよく見られます。時には数百または数千のエラー。

HTMLが証明したように、エラーが発生したときに機能するものを作成すると、エラーが増加します。

無視されるエラーが発生すると、エラーは役に立たなくなり、ノイズに変わります。 TypeScriptの支持者は、おそらくこれらのチームがどのように間違っているのかを教えてくれるコメントに既に集まっており、本当にエラーを修正する必要があります。

エラーを迅速に修正する方法は必ずしも明らかではありませんが、その間、プロジェクトマネージャーは開発者に機能を引き出すよう依頼しています。 TypeScriptはエラーがあっても作業ビルドをコンパイルできるため、開発者が好むかどうかにかかわらず、大規模なプロジェクトがそのような状況になる可能性があります。そのプロジェクトの個々の貢献者に、プロジェクトが彼らに任されていた場合にプロジェクトをその状態にしたことがあるかどうかを尋ねると、おそらく100%が「いいえ」と言うでしょう。

しかし、それは、大規模なチームを持つ大規模なプロジェクトが機能する方法ではありません。

「これはひどいことはわかっていますが、後で修正します。」—これまでに存在したすべての本当の開発チーム。

TSLintおよびより優れたドキュメントがこの問題を解決する可能性があります。それはまだ見られない。

では、次のプロジェクトでTypeScriptを使用しますか?私は開発者ツールが大好きですが、そのオーバーヘッドはその価値よりも厄介なものであると感じています。

TypeScriptを使用すればするほど、スピードよりもスピードが遅くなると思います。そして、それが私をスピードアップせず、バグ密度をあまり減少させないなら、なぜそれを使用しているのですか?

とはいえ、あなたはまだTypeScriptに夢中になるかもしれません。

それはあなたを遅くするかもしれません(私はそれを証明していないことを思い出してください-ただしつこい感じです)が、あなたはそれがあなたをより生産的にするように感じるかもしれません。感情や好みが重要なこともあります。

開発者の幸福が重要です。 TypeScriptの制限に対処していない場合、次のことがわかります。

TypeScriptを使用すると、あなたが幸せになります。

型付き関数インターフェイスの構築と、ドキュメントを読んだりソースコードを調べたりすることなく、次の開発者が関数の呼び出し方法を知っていることを知って満足することがあります。

プロジェクトに多大なオーバーヘッドが追加されることを理解し、それがバグを大幅に削減するのに役立たないことを知って、そこに入ります。

どうするの?開発ツールの魔法。

たくさんのTypeScriptファンを怒らせただけです。 「TypeScriptはダメ、使ってはいけない」と言っているのではありません。「TypeScriptはクールで優れた開発ツールを備えていますが、開発者が認識する必要がある大きなトレードオフもあります。期待されるすべての利点を提供するわけではありません。」

依存性注入

まず、依存性注入が大好きです。いつも使っています。しかし、Angular 2は、依存性注入によってあなたを圧倒します。ドキュメントとユニットテストのレシピを読むと、プロバイダーとモックの依存関係に関するあらゆる種類の情報、および `beforeEachProviders()`を使用したユニットテストが見つかります。すべてを頭で囲むのに時間がかかります。ボンネットの下でng2注射剤を引き出すための多くの魔法があり、それがどのように機能するのか、プロバイダーをどのように使用するのかについての誤解は、初心者にとって本当のこだわりです。

もっと簡単な方法があります。依存関係をインポートし、フレームワークに依存して自動的にクラスコンストラクタシグネチャに詰め込むのではなく、依存関係を取得する関数を記述するだけです。とても簡単で、次のように機能します。

依存性注入(DI)の支持者は、私が単純化しすぎている(同意する)とインスタンス化に取り組んでいない(同意する)と言います。私はそれは重要ではないと言っています。

実際には、Angular 2で最終的には、実際にモックを必要とするもの(ネットワークアクセス、ディスクアクセス、タイマー)のほんの一部をモックするのではなく、ブラックボックス化する必要のあるものすべてをモックすることになります実装の詳細。

これは何度も言ったことがありますが、常識になるまで言い続けます。

モッキングはコードの匂いです。

もちろん、モックが必要な場合もありますが、アプリに `* .mock.ts`ファイルが散らばっている場合は、何か間違ったことをしていることになります。アプリが密結合しすぎている(皮肉なことに、DIの考え方はアプリの結合を弱めることです)、または、モックを必要としないものの多くをモックしようとしています。

全世界に注入してm笑する必要はありません。

ジャスミン

「Mochaの代わりにテープを使用する理由を読んでください」をお読みください。それのほとんどはジャスミンに適用されます。

Jasmineは、英語の文章のように読むことをほとんど試みないAPIを提供し、多くのアサーション機能を提供します。その結果、テストとアサーションを作成する方法は数百万通りになります。つまり、テストとアサーションを理解するには、それぞれを注意深く読む必要があります。

少数のコアアサーションに自分自身を制限する方が良いでしょう。主に平等チェック。大規模なチームですか?それで頑張ってください。

ジャスミンはまた、偶発的に共有状態を助長する可能性のある `beforeEach()`と `afterEach()`への多くの依存関係を奨励します:ランダムテストの失敗を引き起こす可能性があるユニットテストの非常に一般的な問題(ジャスミンテストは、共有状態の使用とテスト順序への依存を推奨しない)。

これらの批判に加えて、ジャスミンにはもう1つ、3 @ + $#| +を狂わせる欠陥があります。 2つのオブジェクトが等しいかどうかを比較すると、1つの大きな行に両方のオブジェクトがシリアル化されて出力されます。言い換えれば、デフォルトのレポーター出力は基本的に#$%!@#$の価値がありません。

[編集者のメモ:記事のこの部分から、!@#$のブリープ音だけの8つの段落を削除する必要がありました。完全な転写物を共有しますが、子供が泣き、子犬がソファの下に隠れてしまう可能性があります。]

チャイは素敵な差分を出力します。テープはこれを印刷します:

良くない1は同じであるべき
---
演算子:等しい
予想:|-
{x:1、y:{z:3}}
実際:|-
{x:1、y:{z:2}}
...

小さなオブジェクトの場合、違いを簡単に確認できます。さらに改善するプラグインレポーターがあります。

開発者は、テストが失敗した場合の違いを明確かつ明確に報告する必要があり、その部門ではJasmineが一目瞭然です。この問題を解決するために優れたブラウザー内レポーターを接続する方法を知っている場合は、コメントしてください。

コアが固定されるのを待っている場合は、息を止めないでください。この問題の未解決の問題は、2014年以降に発生しています。

他のもの

角度のあるものもたくさんあります。フォームとバリデーターなど…しかしもちろん、Reactユーザーはそれらを使用したい場合、すべてのものを利用できます。大きな違いは、Reactユーザーは明らかな場所(Reactのドキュメントなど)で常に最適なソリューションを見つけられないことです。代わりに、Reactユーザーはコミュニティのベストプラクティス、ブログ記事、およびその他の学習リソースに依存して、最良の選択肢を特定します。

すべての余分な「その他」はAngular 2バンドルを膨らませます。 Angular 2 + RxJSはかなり巨大です。ほぼ800kが縮小されました。これは、React + Reduxの約4倍の大きさであり、アプリをすばやくロードしてレンダリングしたい場合、アプリコードに余地を残しません。

これは、私が本当に重要だと思う唯一の大きな、顕著なパフォーマンスの違いであり、かなり重要です。読み込み時間を改善すると、アプリのKPIが大幅に向上します。読み込み時間をミリ秒単位で削ることで、重要なビジネスメトリックの針を動かすことができます。

4倍の大きさ(ほぼ1メガバイト!)は本当に大きな問題です。必要ない場合はロードしないでください。

編集:いくつかのコメンターが指摘したように、ng2にはAhead Of Timeコンパイル(AOT)とツリーシェーキングを行う機能があります。プロダクションビルドを正しく構成すると、アプリで実際に使用されている機能のみを使用してバンドルサイズを大幅に削減でき、最終的なバンドルのフットプリントがはるかに小さくなります。実稼働バンドルを正しく構成することを強くお勧めします。直帰率、コンバージョン率、顧客満足度、解約率に劇的な影響を与える可能性があります。

Angular 2では見つからないReactのスタッフ

Angular 1は、Angular 1と​​同様、HTMLテンプレートに依存しています。

ng2テンプレートの良いところは、基本的に標準HTMLの拡張された形式であることです。

ng2テンプレートの悪い点は、Angular DSLを少し学ばなければならないことです。 `* ngIf`や` * ngFor`のようなもの。

ng2テンプレートのい点は、ミスをすると実行時に失敗することです。時々静かに。 Angular 2テンプレートのデバッグは面倒な場合があります。

編集:これは、AOTを使用すると、Angular 2の最新バージョンで修正されたと言われています。テンプレートエラーはコンパイル時に報告されます。修正をテストする機会はまだありません。

Reactにはテンプレートがありません。代わりに、コンパイル時にJavaScriptにコンパイルされるJSXがあります。

JSXの素晴らしい点は、間違えた場合、実行時を待つのではなく、設計時にリンター、つまりコンパイル時にキャッチされる可能性が高いことです。 Babel、ESLint、および多くのエディターツールには、JSXのサポートが組み込まれています。

JSXのもう1つの優れた点は、それだけでHTML以外のものをターゲットにできることです。カスタムマークアップをターゲットにしたり、キャンバスをターゲットにしたり、ネイティブモバイルUIをターゲットにしたりすることもできます。

JSXの悪い点は、HTMLタグと1対1で正確に一致しないことです。 JavaScript APIとマークアップのフランケンシュタインハイブリッドです。つまり、 `class`の代わりに` className`を使用するなど、その癖を学ぶ必要がありますが、ループや条件などの単純な古いJavaScriptをJSXと自由に混在させることができるので、学習性はng2に勝ると思います。

状態はどうですか?

Angular 2とReactはどちらも、好きなデータ管理レイヤーを使用できます。 2方向のデータバインディングをオプトアウトすることを気にしない場合(これは、とにかくIMOは悪いことです)、独自の状態管理をng2に持ち込むことができます。基本的にRedux + observablesであるngrx / storeをお勧めします。

Reactについては、Redux(ほとんどの大規模アプリ向け)またはMobX(トランザクション状態を必要としない、それほど複雑ではないアプリ向け)をお試しください。

JavaScriptアプリの最新の状態管理の詳細については、「Reduxアーキテクチャを改善するための10のヒント」をご覧ください。

何を選ぶべきですか?

しばらく両方を頻繁に使用した後(もちろん、もっと長く反応する)、Angular 2にはアプリ内でより多くの技術購入と定型文が必要になることは明らかです。

技術の選択肢が好きで、追加の定型的なオーバーヘッドで生活できる場合は、Angular 2を選択してください。

Angular 2の技術の選択に不満があり、よりスリムで規範的でないものが必要な場合は、Reactを選択してください。

もちろん、他のオプションもあります(その一部は非常に優れています)が、大規模なエコシステムと開発者コミュニティには価値があり、React&Angularが使用を支配します。 3分の1もありません。これら2つよりも人気がある唯一のライブラリはjQueryです(はい、まだです)。

踊り続ける。

EricElliottJS.comで無料レッスンを開始してください

エリック・エリオットは、「Composing Software」および「Programming JavaScript Applications」という本の著者です。 EricElliottJS.comとDevAnywhere.ioの共同設立者として、開発者に不可欠なソフトウェア開発スキルを教えています。彼は暗号化プロジェクトの開発チームを構築して助言し、Adobe Systems、Zumba Fitness、The Wall StreetJournal、ESPN、BBC、およびUsher、Frank Ocean、Metallicaなどのトップレコーディングアーティストのソフトウェアエクスペリエンスに貢献しています。

彼は世界で最も美しい女性との遠隔生活を楽しんでいます。