Zone.js
Zone.js は、非同期処理(setTimeout, Promise, イベントなど)をフックしてアプリの状態変化を監視し、自動的にUIを更新するライブラリ。Angularでは、「状態が変われば自動で画面を更新してくれる」仕組みを担っている。たとえば、ボタンをクリックして値を変更したとき、Zone.js が裏でそれを検知し、UIの再描画を自動的に行う。
課題
Zone.jsには便利な面がある一方、以下のような課題がある。
-
パフォーマンスへの影響
多くのグローバルAPIをパッチ(書き換え)して挙動を監視するため、大規模アプリでは性能が低下することがある -
デバッグの難しさ
裏側で自動的に多くの処理が走るため、「何がきっかけでUIが再描画されたのか」が見えづらく、バグの特定が難しくなる -
複雑性の増加
あらゆる非同期処理を監視・フックする必要があり、予期せぬ副作用や思わぬ挙動も起こりやすい -
制御性が低い
開発者がUI更新タイミングを細かく制御しづらく、「パフォーマンス最適化」や「部分的な更新制御」が難しい場合がある
Zoneless と Signal
Zone.jsの課題を解決するために、Angularでは Zone.js に依存しない新しい仕組み Zonelessが導入されている。その中核を担うのが、Signal という新しい状態管理・変更検知の機構。
Zoneless
- Zone.js を完全に排除し、開発者がUI更新のタイミングを明示的に制御できる方式
- polyfills.ts から Zone.js のインポートを削除し、必要に応じて ChangeDetectorRef.detectChanges() やSignal の変更検知によってUIを更新
- 不要な再検知やパッチ処理のオーバーヘッドを減らし、パフォーマンスの大幅改善を実現
- デバッグも容易になり、変更検知のトリガーを明確に把握できる
Signal
- 状態をリアクティブに管理し、変更があった場合のみ効率的にUI更新を走らせるリアクティブプリミティブ
- 変更検知を自動ではなく「必要な時だけ発生させる」、より予測可能で高速な仕組みを提供
- Signal の値が更新されると、それに依存するUI部分だけが再レンダリングされる