Jotaiのdependency trackingは何がすごいか
Jotaiについてツイートしたら、dependency trackingがどうrender optimizationと関係するかについて聞かれました。
ブログ記事にしようかと思いつつ、ひとまず、ツイートで返信しようと思うも文字数が足りない。そこで、Excalidrawで書いて、Shareable Linkにしました。
ついでに、画像も貼り付けました。
意訳
ZustandとかReduxではグローバルステートにおけるレンダリングの最適化をselectorを使って行います。しかし、selectorはReactのrender phaseで実行され、新しいオブジェクトを生成すると別物と扱い無駄なレンダリングが発生してしまいます(これを解決するためにreselectやproxy-memoizeなどのライブラリが存在します)。そこで、Proxyを使った最適化をReact-Trackedで実現しました(ちなみにこれはusage trackingと呼んでいます)。のちに、これをベースにValtioが誕生しました。Proxyを使った最適化は挙動が多少マジカルなため好まれない場合があります。そこで、atomベースのステートで最適化しようとしたのがJotaiです。アイデアとしては新しくなく、Recoilだけでなく、observable系の仕組みで昔から実現されていたものです。atomベースのステートの場合はdependecy trackingにより、selectorのようにrender phaseで実行する必要がなく無駄なレンダリングが発生しません。
何がすごいか
タイトルにした何がすごいかですが、何もすごくないというか、Proxyベースの最適化と比べると依存関係の表現が明示的なことです。
const sumAtom = atom((get) => get(countAtom) + get(anotherCountAtom));
と書いてあれば、sumAtom
がcountAtom
とanotherCountAtom
に依存していることが明確です。実装としても、get()
を記録しているだけで、その先のプロパティアクセスなどは追跡しません。Proxyのような隠れた仕組みを一切使わずに済んでいます。
Dependency trackingはコンパイル時に行うわけではなく実行時に行います。なので、x ? y : z
のような動的な表現が可能です。xがtrueの時はyに依存しますが、zには依存しないことになります。基本的な仕組みがシンプルなので、挙動も大抵期待通りになります。
結局、何がすごいかというと、挙動を予測しやすく期待を裏切らないことでしょうか。
おまけ
なぜブログ記事になっていなかったかというと、本の方に書いたからだと後から気づきました。
あと、元のツイートはこちら。JotaiとWeakMapの類似性について。
リンク集
Jotai Friends のテックブログです。 React状態管理ライブラリJotai(jotai.org)を新たな選択肢に。 エンジニアの皆さんが安心してJotaiを採用できるように支援します。 Powered by twitter.com/t6adev
Discussion