技術記事以外

技術記事以外の振り返りやその日学んだことのちょっとしたメモなどを置く予定です

今日の学習メモ

Angular Change Detection - How Does It Really Work?

  • Angularの起動時にはlow-levelのAPIの上書きが行われている。例えば、addEventListenerを上書きすることで「ネイティブのaddEventListenerを実行→Angular独自の変更があるかどうか、あれば再描画する」という挙動にする。
  • このPatchingを担当しているのがZone.js。Zone.js自体はシンプルに複数のJSのVMのターン(? どう訳すと適切かな…)に渡って生き残る実行コンテキスト。このように内部でChangeDetechtionを走らせるのに使われている。
  • なので、IndexedDBなどのZone対象外のAsyncAPIではChangeDetechtionを走らせることが出来ない
  • コンポーネントにはChangeDetechtorが作られて、テンプレート内で使われている変数が変わったかチェックしている。逆にいうと、例えばオブジェクトの中にテンプレートで使われていないプロパティがあったとして、その変更は追いかけない。(デフォルトの挙動)
  • ところでなぜChangeDetectorのコードを共通しないのかというと、JavaScriptVMに理由がある。動的なプロパティの比較はVMJITコンパイラでネイティブコードに最適化することが難しいから。一方で、各コンポーネントごとのDetectorは私たちが普通に書くように直接プロパティにアクセスしている。結果として、この状態でも高いパフォーマンスを維持できる。
  • もちろんコーナーケースはある。そういう時はonPushを使う。onPush@Inputの変化時のみしか再描画が走らない設定なので、例えば@Inputのオブジェクトを直接いじっても参照が変わらない限り再描画されない。だが一方で本当に@Inputの変化時のみしか再描画されないかというとそんなことはなくて、コンポーネントないのイベントが発火した時も走る。
  • とはいえミュータブルなオブジェクトを扱うコンポーネントに大して使うと思わぬバグを起こしたりするので使いどころは見極める必要がある。