概要
synstate-dom は、synstate の Observable を DOM に直接束縛する UI ライブラリです。JSX を書いて、値を置きたい場所に Observable を渡すだけで動きます。Solid のようなコンパイラは要りませんし、仮想 DOM もありません。
synstate-dom を使う理由
Section titled “synstate-dom を使う理由”synstate-dom は SynState のための UI ライブラリです。SynState のランタイムに UI としてできるかぎり直接つながるように作っています。SynState のオペレーターで組んだグラフは、それを束縛した DOM のノードで終わり、途中で値を別のライブラリのモデルに変換することも、値を読むためにコンポーネントを再実行することもありません。
- SynState の速さがそのまま画面に届きます。 SynState のベンチマークの概要では、SynState はどのシナリオでも最速のライブラリの 2.7 倍以内に収まります。すべてのシナリオで計測したライブラリのうち、最悪のケースでも1桁倍に収まるのは SynState だけです。synstate-dom はそのグラフとページの間に何も挟みません。
- シンプルな API で、遅くなる場面が少ない。 synstate-dom は、ベンチマークの 1 行だけで勝つための書き方を増やさず、1 つのことに 1 つの書き方を保ちます。変換した値はどこに束縛するときも
source$.pipe(map(fn))です。js-framework-benchmark の操作では、最も遅い操作でも最速のライブラリの 1.56 倍です。Solid・Preact・Preact + Signals には及びませんが、最も遅い操作が 3.79 倍の React を大きく下回ります。詳しくはベンチマークを見てください。
-
コンポーネントは 1 回しか呼ばれません。 マウント時に実行されて DOM の記述を返したら、それきり二度と呼ばれません。その後に変わるのは、渡された Observable に束縛した DOM だけです。
-
更新は葉に直接届きます。 状態が変わると、synstate がその変化をグラフ全体に 1 回の同期的でグリッチのない伝播で伝え、束縛された属性・プロパティ・テキストノードにそれぞれ直接書き込みます。差分を取ることはありません。
-
依存は値として渡します。 コンポーネントが依存するのは、渡された Observable そのものです。そのため、実行中に依存を追跡する必要もなければ、Solid のように JSX の式を遅延させるためにコンパイルする必要もありません。詳しくはコンパイラなしで成り立つ理由を見てください。
-
何がリアクティブかは型を見ればわかります。 データを受け取るスロットは
Bindable<T>、つまり初期値ありの Observable かconstant(...)を受け付けます。素の値を渡すと型エラーになるので、うっかりスナップショットを渡してしまうことがありません。詳しくは Bindable を見てください。Solid では、シグナルを読んだ式を渡しても固定値を渡しても props の型は同じ素の
Tです。なので、リアクティブに更新させたい値とそうでない値を型で区別できず、間違った方を型で弾くこともできません。コンポーネント本体で props を一度だけ読んだり分割代入したりすると更新は黙って止まってしまい、それに気づかせてくれるのは lint(eslint-plugin-solid のsolid/reactivityとsolid/no-destructure)だけです。synstate-dom では、更新されるかどうかはBindable型かどうかそのものなので、シグネチャを見ればわかりますし、tscがチェックしてくれます。また props は値を読み出したものではなく
Bindableそのものなので、props だからといって特別な扱いは要りません。分割代入しても、デフォルト値を付けても、残りをまとめて渡しても、コンポーネント本体で計算しても構いません。その代わり、更新し続けたい派生値は JSX の中の式ではなく、Bindable として(mapBindableやderiveBindableで)組み立てる必要があります。詳しくは props は普通の JavaScript の値を見てください。 -
後始末はスコープがしてくれます。
If/Matchの各分岐とForの各行は、それぞれスコープの中でマウントされます。マウント中に作った派生と購読はそのスコープに属し、スコープと一緒に破棄されます。詳しくはライフサイクルとスコープを見てください。
(まだ)しないこと
Section titled “(まだ)しないこと”- サーバーサイドレンダリングとハイドレーション。
- context。部分木で必要なものは props で渡すか、ストアを import してください。
- Preact Signals や React のような、コンポーネントの再実行。