Webエンジニア向けプログラミング解説動画をYouTubeで配信中!
▶ チャンネル登録はこちら

【ITニュース解説】Why Angular Isn’t the Observable Framework You Think It Is

2025年09月14日に「Dev.to」が公開したITニュース「Why Angular Isn’t the Observable Framework You Think It Is」について初心者にもわかりやすく解説しています。

作成日: 更新日:

ITニュース概要

AngularはRxJSと連携するが、複数の反応モデルを使い分け複雑になりがちだ。Rimmel.jsはストリーム指向で、RxJSストリームをUIに直接繋ぎ、単一モデルでシンプルに開発できる。`async`パイプやシグナルなど不要で、よりクリーンで一貫性のあるコードが書ける。

ITニュース解説

Angularはウェブアプリケーション開発でよく使われるフレームワークの一つであり、非同期データ処理に「Observable」という概念を取り入れていることで広く知られている。多くの開発者は「Observable」と聞くと、データの流れを表現する「ストリーム」を扱う「RxJS」ライブラリとAngularが結びついていると考え、データが変化したときにUIが自動的に更新される「リアクティブ」な仕組みのフレームワークだと認識している。しかし、実際のAngularとObservableの関係は、必ずしも開発者が思い描くような完全に統一されたものではない。

Angularは確かにRxJSと連携しているが、その内部ですべてのデータフローが完全にObservableで統一されているわけではない。Angularで非同期データを扱う場合、開発者はRxJSのストリームという考え方と、Angularが提供する独自のリアクティビティの仕組み、例えば「asyncパイプ」や、最近導入された「Signals」といったものを同時に扱う必要がある。

「asyncパイプ」とは、HTMLテンプレート内でObservableから非同期に届く値を取り出して表示するためのAngular独自の機能である。しかし、これを使うと、アプリケーションのあちこちに| asyncという記述が必要となり、コードが冗長になりがちである。また、Observableの値を自分で管理する場合には、「BehaviorSubject」というRxJSの特定の機能を使って現在の値を保持し、手動で次の値を流し込むようなコードを書く必要がある。さらに、Observableは適切に「unsubscribe」(購読解除)しないと、メモリリークの原因になることもあるため、開発者は常にその管理を意識しなければならない。そして、Angularは最近、「Signals」という新しいリアクティビティの仕組みを導入した。これは、既存のRxJSと並行して動くため、開発者はこれまでのRxJSの知識に加えて、新たにSignalsの概念も学ぶ必要が生じ、システム全体が複雑になる原因となっている。このように、AngularではRxJSのストリームとAngular独自の仕組みの間で、常に考え方を切り替えながら開発を進める必要があるため、一貫性がなく、洗練されていないと感じられることがある。

このようなAngularの課題に対し、「Rimmel.js」という新しいUIライブラリが登場した。Rimmel.jsは、最初から「ストリーム指向プログラミング」という考え方に基づいて設計されている。これは、Observableが単なる補助的な機能ではなく、アプリケーションの中核をなす、中心的な存在であるという思想である。Rimmel.jsでは、ユーザーのクリックなどのイベント発生源も、データを受け取って表示するUIの部分も、すべてがストリームとして扱われる。これにより、アプリケーション内のデータの流れが一本化され、開発者はRxJSのストリームという単一のパラダイムで、UIのイベント処理からデータの表示までを一貫して記述できるようになる。

例えば、画面上にボタンがあり、ボタンがクリックされるたびに数字が増えていく「カウンター」の機能を作る場合を考えてみよう。

Angularでこのカウンターを作るには、まずBehaviorSubjectを使って現在のカウント値を保持し、それをObservableとして公開する。そして、ボタンのクリックイベントが発生したときに、increment()というメソッドを呼び出し、その中でBehaviorSubjectnext()メソッドを使って手動でカウント値を更新する。最後に、テンプレートで{{ count$ | async }}のようにasyncパイプを使って、Observableから値を取り出して表示する。このように、Angularではデータの変更とUIの表示に異なる記述や手順が必要となる。

一方、Rimmel.jsで同じカウンター機能を作る場合、BehaviorSubjectで初期値を持つストリームを作成し、pipe(scan(x=>x+1))というRxJSのオペレーターを使って、ストリームに値が流れるたびにインクリメントされるように定義する。そして、HTMLテンプレート内で、ボタンのonclick属性にこのストリームを直接バインドし、表示したい場所にも同じストリームを直接埋め込む。Rimmel.jsではasyncパイプのような特別な記述は不要であり、手動で値を更新する命令的なメソッドも必要ない。イベントもデータもすべてストリームとして扱われ、UIと直接結びつくため、コードは非常に簡潔で直接的になる。

Angularが最近導入した「Signals」は、「きめ細やかなリアクティビティ」を実現し、無駄な再計算を減らすことを目的としている。しかし、Signalsの導入は、開発者にとって新たな複雑さを生み出す側面もある。なぜなら、これまでのRxJSによるObservableというリアクティビティの仕組みに加えて、Signalsというもう一つの仕組みを学ぶ必要が生じるためだ。これにより、非同期で取得したデータはObservableとして流れ、それをAngularのUIで表示するためにSignalsに変換する必要があるという、二重のデータ変換が生じる。また、UIからのイベントは引き続き命令的な手順を経て処理されるため、結局、非同期処理にはRxJSのストリーム、UIのレンダリングにはSignalsというように、アプリケーションのロジックが二つの異なるリアクティブモデルで分断されてしまう。開発者は、これら二つのモデルの間で常に翻訳作業を行うような状態になり、学習コストと開発の複雑さが増すことになる。

対照的に、Rimmel.jsではSignalsのような追加のレイヤーは全く不要である。Rimmel.jsが採用するObservableは、もともと非常に表現力豊かで、組み合わせやすく、非同期データ処理だけでなく、アプリケーションの複雑な状態管理にも十分に対応できる能力を持っている。Signalsを導入しないことで、Rimmel.jsの開発者は常に「ストリームが入力され、ストリームが出力される」という一つの明確なメンタルモデルで開発を進めることができる。これにより、コードはより整然とし、軽量で、直接的で、そして予測しやすくなる。

Rimmel.jsは開発者にいくつかの大きなメリットを提供する。まず、真の意味での「ファーストクラスのObservable」を体験できる。これは、特別なパイプやラッパーを介さずに、Observableが直接アプリケーションのあらゆる部分で活用されることを意味する。次に、コードが格段にクリーンになる。アプリケーションのすべての要素がストリームという共通の言語でコミュニケーションを取るため、一貫性が保たれ、理解しやすいコードになる。また、ストリーム指向プログラミングは、アプリケーションの複雑さが増しても優雅にスケールできるため、将来性も高い。そして、もしあなたがすでにRxJSの知識を持っているならば、Rimmel.jsのほとんどの概念はすぐに理解できるだろう。これは、既存のスキルセットを最大限に活かせることを意味する。複数のリアクティビティシステムと格闘する代わりに、開発者は本来の目的である新機能の構築に集中できるようになるのである。

まとめると、Angularは「Observable」と深く結びついているという一般的なイメージがあるが、実際にはRxJSのストリーム、Angular独自のasyncパイプ、そして最近導入されたSignalsという複数のリアクティブシステムを開発者が同時に管理する必要があり、常に思考を切り替えるコストがかかっているのが現状である。これに対しRimmel.jsは、最初からストリーム指向のパラダイムを徹底することで、Observableをアプリケーションの基盤となる自然な要素として位置づけている。Rimmel.jsを使うことで、開発者は既存のRxJSの知識をそのままに、よりシンプルで一貫性のある開発体験を得ることができ、アプリケーションの構築に集中できる環境が提供されると言える。

関連コンテンツ