Angular 2/4が狭量で遅すぎる理由

(注:2017/08/30、いただいたフィードバックを元に翻訳を修正いたしました。)

TL;DR — AngularJSのアイデアは、2012年には妥当と言えましたが、2017年においてはそうとは言えなくなっています。JSのエコシステムは、成熟度、柔軟性、および生産性の面で、あっという間にAngularの前を通り過ぎてしまいました。現在では、webpackやフロントエンドのNPM、成熟したツールとライブラリのエコシステムを背景として、大型チームを有する企業であっても、ReactやVueなどの軽量なJSライブラリを使用することで、大規模で柔軟性のあるSPAを、適切な設計で維持することが容易になっています。

加えて、Angular 2/4の問題が散見された3年の開発期間や議論の余地があるアーキテクチャの決定方針が、多くの企業にこの新しいフレームワークの採用を躊躇させているようです。


2017年現在、フロントエンドアーキテクチャの構築や書き直しを迫られた人たちにとって、ReactとAngularの違いは気になるところだと思います。ReactとAngularについては、ここ数年にわたり活発な議論が行われてきました。これをたとえて、コーラ対ペプシとかフレームワーク対ライブラリなどと言う人もいますし、トレードオフの関係とか、どっちにも長所/短所があるとか言う人もいます。しかし、現時点において、Angular 2/4が以前のAngular JSのようなトップの地位に返り咲くのは、容易でないことは想像に難くないでしょう。

2012年:AngularJSが人気を得た理由

AngularJSは、簡単な双方向データバインディング、MVCアーキテクチャ、組み込みモジュールシステム、依存性の注入、ルーティングパッケージなどの特徴により、高い人気を得ました。当初は、2009年にMisko Heveryによって趣味のプロジェクトとして構築されたものですが、2012年の1.0リリース直後、そのフレームワークは瞬く間に軌道に乗り、すぐにフロントエンドの開発者にとって、最も人気の高いSPAフレームワークとなったのです。

2012年当時、JavaScriptのエコシステムでは、KnockoutやBackbone、Ember、Angular、そしてその他諸々の多様なフレームワークがシェアを競っていました。ES6はまだ出てきてはおらず、NPMはフロントエンドのコードには使われていませんでした。ライブラリもフレームワークも成熟していたとは言えません。そんな中、KnockoutJSのSteve Sandersonは、 “Throne of JS” の会議を受けて、フロントエンドの当時の現場について素晴らしい考察を発表しました。

晴天の霹靂のごとく現れたAngularJSは、Web開発者のために多くの問題を解決しました。シンプルなSPAの場合、それは正に生産性の勘所を押さえていたと言えるでしょう。ツールは拡大し始め、カスタムディレクティブライブラリがリリースされ、プラットフォームは驚くべき速さで成長しました。

しかし、開発者が大型チームを組んで、専門的でリッチなフルスケールのアプリケーションを長期スパンで構築しようとした時、その限界が見え始めてきたのです。双方向データバインディングやウォッチャー、$スコープ変数、状態管理、factory/serviceのような混乱を招く反復的な抽象化、そしてその他の多く問題が、本番環境においてAngularJSの使用を困難にしていました。

Angularの人気がピークだった2014年、Angular開発チームは、従来のものとは互換性のない全く新しいフレームワークを作ることを発表しました。そしてこれを、半ば混乱的に、半ば欺瞞的にAngular 2と名付けます。

Angular 2.0の発表が裏目に – JAXenter 最近のAngular 2.0の発表を受けて、開発者はフォーラムに氾濫し、コメントセクションには怒りの… jaxenter.com
Angular 2.0

議論を呼んだこの発表は、開発者コミュニティで多くの懐疑と批判にさらされました。アップグレードパスが提供されないため、アプリケーションがAngularJSで構築されていた場合、最初から書き直さなくてはなりません。コミュニティが大混乱の中、一部の人はAngular 2がその約束を果たせるかどうか見守っていましたが、他の人はフロントエンド開発において、別の場所に目を向けるようになりました。

2013年:Reactがフロントエンド開発において革新を起こす

2013年、JavaScript fatigue(JavaScriptの疲弊)の渦中において、Facebookは自社の本番環境において2年以上使ってきたReactをオープンソース化します。ReactはMVC(モデル・ビュー・コントローラ)のVという謳い文句で発表され、その単方向データフローと単純な機能コンポーネントモデルで、JSフロントエンドのコミュニティを完全に揺るがしました。

2013年当時、Reactは、Angularや他のJSフレームワークで主流だった双方向データバインディングの世界に忽然と現れ、 “それは良くないコンセプトだ” と宣言したのです。双方向データバインディングは、シンプルなアプリケーションでは優れていますが、多くの状態を有するより大きな規模の製品では、簡単にスパゲッティになる可能性があり、予測できない副作用が数多く発生する事態につながります。2013年の主要な機能だった双方向データバインディングを、Facebookはバグだと言いました。そして、それは正解だったのです。Ember、Angular、Vueなども、後に単方向モデルを採用することになります。

Facebookは、状態の管理について先導するような動きを見せませんでしたが、そのソリューションとして、実際のライブラリやフレームワークというよりも、どちらかと言えばパターンに近い “Flux” を提供していました。そして2013年、Reactが発表されるやいなや、FlummoxAltFluxxorMartyJSMcFlyなど、数多くのFlux実装がシーンに登場しました。

https://facebook.github.io/flux/img/flux-simple-f8-diagram-explained-1300w.png

“Flux fatigue(Fluxの疲弊)” が訪れていた矢先の2015年6月2日、Dan AbramovがReduxをリリースします。Elm言語に触発されたReduxは、予測ができ機能的でメンテナンス可能な状態管理をJavaScriptにもたらしました。バックエンドサーバ技術では一般的なソフトウェアアーキテクチャパターンのイベントソーシングに類似したパターンによるactionとreducerが導入されており、その明示的かつ宣言型のデータ管理モデルを通じて、状態管理が簡単になり、アプリケーションとのスケーラビリティも向上しました。

これにより、タイムトラベルデバッガやホットモジュールリローディング、シンプルで簡単なundo/redo機能など、非常に強力なフロントエンド機能が実現しました。また、機能的なデザインパターンが奨励されており、コードのテストや推論が簡単に行えるようになっています。

Reduxとは?(または、いかに私がJavaScriptの “状態コンテナ (state container)” に恋に落ちたか) Hack Reactorにおいて、チームの最終プロジェクトで使うFlux実装を模索していた時、友人の… www.youhavetolearncomputers.com
Understanding Redux

本番環境でReact-Reduxを使って学んだ6つの教訓数ヵ月前、私はBizzaboで、Backbone + RequireJS + Handlebarsからどのように移行したかについてブログを公開しました…medium.com
6 lessons learned from

Reduxは、Reactコミュニティに嵐を巻き起こしました。そのインパクトから2年経った今でも、熱狂は続いていると言えるでしょう。PayPalやMozilla、AirBnBなど、数多くの大手ソフトウェア企業で利用され、人気の高いGraphQLクライアントライブラリであるApolloの基盤を形成しています。また、他のフレームワークでは、状態管理ソリューションとして採用されています。現在においては、Reactと組み合わせる際の、事実上の状態管理ソリューションです。

一方で、Reactのその他のイノベーションは、フロントエンドの変革を続けました。

サーバ側のレンダリング

ReactのUIは機能的に抽象化されており、どの環境でも実行できます。多くの人が、初期の段階でこれを認識し始め、Node.jsと組ませて、サーバ側でレンダリングを提供するようになりました。Reactだけでも非常に高速ですが、サーバ側のレンダリングと組み合わせると、全てのデータはWebページが読み込まれる前にビューにロードされ、Node自体でレンダリングされます。これにより、SPAを検索エンジンに適したものにすることができるようになりました。

2015年:React Native始動

2015年3月、FacebookはiOS向けにReact Nativeを発表しました。この発表で、Reactの機能的なUIコンポーネントの抽象化を通じて、モバイルアプリケーションをネイティブで記述できることが初めて実証されたのです。

Facebookは、 “1回の記述で、端末を選ばず実行できる” と約束する代わりに(これは時として、 “1回の記述で、全ての端末でデバッグが必要” と冷笑されることがあります)、 “1回学習すれば、端末を選ばず記述できる” という哲学を打ち出しました。その根底には、大部分のコードはプラットフォーム間で共有することができるものの、個別に対処が必要なニュアンスの違いがプラットフォーム間には存在するという考えがあります。React Nativeとは、このプラットフォーム間の違いに対処するためのインターフェイスを提供するものです。

Androidのサポートについても、その約半年後に開始されました。生産性の向上は驚くべきもので、開発者は、モバイルプラットフォーム間でコードの90%以上をネイティブレンダリングパフォーマンスで共有できます。

なお、Windowsアプリケーションを構築するためのReact Nativeライブラリが、後にMicrosoftからリリースされています:https://github.com/Microsoft/react-native-windows

現在では、InstagramやFacebook、Wal-Mart、Baidu、Skype、Discordなどといった巨大企業のアプリケーション開発に、React Nativeが利用されています。

ネイティブiOS(Swift)とReact-Nativeのパフォーマンスの比較 React-Nativeは、JavaScriptのみを使用してアプリケーションを構築できるハイブリッドモバイルフレームワークです。しかし、他のハイブリッドとは異なり… medium.com

Comparing the Performance

ReactとReact Nativeに競争上の優位性があることはほぼ確実で、Facebookが製品スイート内の4つのアプリケーション(WhatsApp、Messenger、Facebook、Instagram)において、どのようにSnapchatに似た “ストーリーズ” を同時に立ち上げたかという経緯を見れば、その優位性がよく分かります。

FacebookのSnapchatコピーは4度目。全てのアプリがそっくりに Facebookは、それぞれのコアサービスに対して、固有のアイデンティティを与えることには関心がないようだ。 www.recode.net
Facebook copied Snapchat

Snapchatの成長を効果的に阻害しています。

Snapchatのユーザ数、Facebookの模倣ソフトウェアにより大打撃 Facebookは水曜日にユーザ情報の一部を公開 – 少なくともSnapchatのライバル製品のいくつかは… www.cnbc.com
Facebook's copycats appear

Facebookが、こうしたことを素早く実行できた鍵がReactであったと推測するのは難しいことではありません。

NPM、ES2015、Babel、webpack

Reactの使用を通じて、Facebookが飛躍的に革新を続ける一方で、フロントエンドのJavaScript業界においては、いくつかの重要な開発が並行して行われてきました。

JavaScriptにおいては、特定の主要な言語機能が欠如しているという苦しい状況が続いており、特にクラス、モジュール、ラムダの全てが欠けていましたが、ES2015で、これら3つに加え、その他多くを含む新しい言語機能が導入されました。また、JSが抱えていた長年にわたる問題の1つが、新しい言語機能に対するクロスブラウザサポートですが、Babelにより、ES2015をES5互換のJSにコンパイルすることで、IEやChrome、Firefox、iOSなどがサポートを開始する前でも、こうした新しい言語機能の全てを使用できるようになりました。

webpackでは、CSS、JS、HTMLなどのプロジェクト資産を簡単にバンドルするための素晴らしいツールを使うことができる他、数年前には考えられなかったような強力な機能が搭載されています。細分化、レイジーローディング、Tree Shaking、そして最適化の機能などは、今やどんなWeb開発者でも利用可能です。

webpackのバンドルシステムは、もう1つの強力な機能を実現しました。それが、フロントエンド向けのNPMです。Node.jsのデフォルトパッケージマネージャとして、また世界最大のソフトウェアレジストリとして、NPMは公開されているJSライブラリの全てを実質的にホストしています。JavaScript用のアプリストアと言ったところでしょうか。

2013年には、JSライブラリと依存関係をアセンブルし、フロントエンドコードを保守可能な形で構築することは困難でした。しかし2017年においては、こうしたツールのおかげで簡単に行えるようになっています。

2016年9月:Angular 2がついに始動…

2017年3月:Angular 4に更新

Googleの2人の開発者Evan YouとRob Eisenbergが離れるなどで(2人はそれぞれ独自のフレームワーク、VueAureliaを開発)、Angular 2の開発サイクルには大きな遅れが生じていましたが、やっとのことで表舞台に登場しました。

9月から3月までの暫定的な期間には、CLIが修正され、ルータの新バージョンがリリースされ、さらにいくつかの大きな変更が施されました。チームはAngular 4を単なるAngularとして立ち上げ、現在は半年ごとの更新に向けて開発に取り組んでいます。

Angular 2/4およびそれ以降のバージョンは、2014年にチームが初めて発表したものとは完全に異なっており、TypeScriptとRxJSで構築されています。この2つは、型、デコレータ、およびリアクティブやオブザーバブルの状態管理用のサードパーティ製ツールです。

Angular 2/4は、TypeScriptデコレータ、SystemJSモジュール、RxJSオブザーバブル、そしてHTMLに類似したAngularカスタム構文に大きく依存する、全く別のコンポーネントシステムと言えるでしょう。

コンポーネントシステムは、最新のUI開発において中核を成します。Reactは、W3C標準がWeb Componentsで実際には一度も好転させることができなかったことを、うまく解決しました。

Angularのコンポーネント構文はReactよりも明らかに冗長です。同じ出力を記述するにも、コードの量は10倍ほど必要で、ワイヤリングや形式の仰々しさがより大切にされます。JSファーストの理念を採用しておらず、ロジックをHTMLの中に置くため、テストも推論も難しくなりますし、使える機能もAngularのカスタムDSLに制限されます(Reactのようなチューリング完全なJavaScript XML(JSX)は使えません)。Angular 4のリリースノートでは、新しい機能として、*ngIfによる “else” を勧めるまでになりました。

Angular 4がリリースされたのは2017年です。2012年にAngularJSが発表された世界とは、その状況が大きく異なっています。Reactよりも冗長な構文と多くの人が本番環境で問題を抱えている重量級のツールチェーンでは、Reactよりもパフォーマンスや保守性を向上させることはできません。

先行者のReactが、数ある技術(ネイティブアプリからVR、サーバ側レンダリング、ホットモジュールリローディング、CSSモジュール、Sketch統合まで)で優位に立っている現状では、Angular 4が追いつくのはかなり困難と言えるでしょう。2017年の現時点では、どのような形であれ、Reactを超えるまでには至っておらず、その能力と成熟度において、Reactエコシステムのはるか後方に位置していると言わざるを得ません。

Reactの方がシンプル

Angular 2/4には、現在進行中の互換性を破る変更に将来的なバージョンで対応するため、500を超える最上位のAPIの概念が導入されています。

生成されるのは、膨大なファイルサイズを形成する重いコードです。事前コンパイラを使用すると、Closureコンパイル後でもソースより3~5倍大きいファイルが生成されます。

Reactの方が、パフォーマンスが高い

Reactのベンチマークは、一貫してAngular 2/4よりも優れた性能を示しています:https://auth0.com/blog/more-benchmarks-virtual-dom-vs-angular-12-vs-mithril-js-vs-the-rest/

疑わしい主張: “Angularは大型チームに最適”

大企業にとっては、フレームワークの性能面でAngularの方が適しているという主張を聞くことがよくあります。しかし、この主張には、本番環境での実績やその履歴などによる裏付けが一切ありません。それどころか、現状では大企業の本番環境でAngular 2/4が使われているのを目にすることさえほとんどないのです。ベータ登場から9ヵ月未満であることを鑑みると、これはさほど驚くべきことではないでしょう。

また、ある企業が大規模なコードベースをReact/ReduxからAngular 2/4に移し、生産性、保守性、または性能が向上したという例もありません。

互換性を破る、困難に満ちた変更を伴う開発が、継続的に3年間続けられた後でも、当初の評価は分かれています

テクノロジーレーダー | 2017年に台頭するテクノロジートレンド | ThoughtWorks ThoughtWorksテクノロジーレーダーにおける言語とフレームワークの四分円に注目。最新情報をキャッチ… www.thoughtworks.com
Technology Radar

現時点では、大企業の本番環境において優れた結果とユーザエクスペリエンスを提供できると証明することが、Angular 2/4の責任であると私は考えています。しかし、これは長年にわたる約束や宣伝にもかかわらず、いまだに達成されていません。

企業が目指しているのは、歴戦の成熟したツールを使用して構築された、保守性とパフォーマンス性の高いソフトウェアを築き上げることでしょう。

優れたフレームワークには、安定性、アクティビティ、エコシステム、コミュニティ、学習曲線、市場内のスキル、および移行の容易性が必要です。

Reactは、6年の間に培った成熟度とFacebook規模での保守性を証明しています。そして、TwitterSlackAtlassianNetflixSalesforceMicrosoftAppleQuipWal-MartWordPressNYTimesなどといった企業の複雑なシステムで使われているという実績もあります。これらの企業を通すことで、制作上の利点はより明確になりますし、これらのシステムが生み出すユーザエクスペリエンスは、Reactが達成したものを映し出す鏡になると思います。

ReactはAngularよりもはるかに安定しています。また、何らかの変更がある際には、コードベースを自動的に更新するコード用モッドがFacebookからリリースされます。

Angularの分裂したエコシステム

Angular 2/4およびIonic 2/3は互換性のない形で完全に書き直されているので、AngularJS向けに記述されたディレクティブやモジュールは、この新しいフレームワークでは無効だということに注意してください。つまり、この2017年において、Angular 4とIonic 3で作業を始めた場合、豊富なカスタムディレクティブを持つAngularJSのエコシステムは利用できないことになります。

JSコミュニティでは、Angular 2/4に10倍ほどの差を付けて、VueやReactなどの軽量フレームワークに移行しています。

NPMパッケージの数

React:31,654
React Native:5,521
Vue:4,657
Angular 2:4,510
Angular 4:527
Ionic 2:207
Ionic 3:31

あなたが2017年にアプリケーションに着手したとした場合、どの程度、カスタム作業をしたいと思いますか? 全てを自分自身で展開し、エコシステムの拡大を望むか、あるいはAirBNBやFacebook、PayPal、Microsoft、Apple、Yahoo、Lyftなどの世界的なフロントエンドの重鎮たちによってオープンソース化されたリッチで成熟したコンポーネントのエコシステムを利用するか、どちらがいいでしょうか。

Facebookは本番環境でReactの試験運用を繰り返し行う。一方、Googleはそれほど行わない。

Googleが作成したツールだと聞いて、多くの人がAngularを選択します。Googleなので、Googleのフロントエンドアプリケーションで主に使用されているフレームワークだと想定し、従ってGoogle規模の本番環境でその有用性が実証されたと考えるわけです。しかしその前提は間違えています。実際のところ、Googleでは、私たちになじみのある多くのアプリケーション(検索、ニュース、Gmailなど)にClosureを使っています。

Closureライブラリ| Google Developers 強力で効率的なJavaScriptを作成 developers.google.com

また、YouTubeで使われているのはSPFです。

SPF YouTubeの迅速なナビゲーションとページ更新のための軽量JSフレームワーク youtube.github.io

このように、AngularはGoogleでの制作にはほとんど使用されていません。GoogleのWeb上の特性は、迅速なダウンロードと実行がその基盤を成していますが、それはAngularが光り輝ける分野ではないのです。

戦いの終結:Reactの勝利

Angularのチームが瞬きをした瞬間、JavaScriptのエコシステム全体がその前を通り過ぎていってしまいました。企業並みのWebアプリケーションを構築したい場合、選択するツールのファーストオプションは、大企業において本番環境で使用されている歴戦のライブラリでしょう。

2017年において、Reactはフロントエンド開発の有力な選択肢です。現在のところ、GitHubでは4番目に星印が多いリポジトリで、JavaScriptのフレームワークとしては、過去最高の人気を得ています。

NPMでの毎月のダウンロード数440万回は、その数において現在のAngularの月間ダウンロード数140万回の3倍以上であり、成長の度合いも3倍に達しています。

https://i2.wp.com/wptavern.com/wp-content/uploads/2016/10/state-of-javascript-survey-frontend-framework-satisfaction.png

2016年に9,000人のJS開発者を対象に行われた調査では、Reactが92%の開発者継続率であるのに対し、Angular 2は64%でした。Reactのダウンロード数が3倍以上で、成長速度も3倍、そしてAngularの開発者継続率がReactの約3分の2だとすると…Reactに軍配が上がることは一目瞭然です。

http://stateofjs.com/2016/introduction/

Reactとそのエコシステムは、電光石火のような反応の、保守可能な開発に役立つ強力で生産的なフロントエンドスタックを築き上げてきました。そしてそれは、誇大な宣伝ではなく、本番環境の堅実な結果に基づいたものなのです。

Facebook/React React – ユーザインターフェイスを構築するための、宣言型の効率的で柔軟なJavaScriptライブラリ
github.com

facebook.react

UI開発の未来は、ReactやVueのような軽量JSフレームワークの手の中にあります。Angular 2/4はあまりにも狭量で(過剰で)、遅すぎるのです。