TanStack Redactは、ReactのコンポーネントやHooksの書き方を保ちながら、実行時の実装を置き換える軽量ランタイムです。新しいUIの書き方を覚えるより、既存のコードを残して配信するJavaScriptを減らしたい。その用途で検討する候補になります。
ただし、Reactと同名のAPIがあることと、同じ挙動になることは別です。Redactは同期描画を選び、描画の優先順位付けや中断・再開を担うconcurrent schedulingを実装していません。導入前に見るべきなのは、サイズ差だけでなく、この省略が自分の画面にどう響くかです。
importは残せるが、RSCまで置き換えるわけではない
公式READMEの導入方法は、@tanstack/redactを追加し、Viteに@tanstack/redact/viteのredact()プラグインを組み込む形です。アプリ側のreactやreact-dom/clientからのimportは維持し、プラグインがRedactの実装へ解決します。JSX用のエントリーポイントも対象です。
プラグインはクライアントとSSRのビルドを扱います。一方、React Server Componentsの環境は本家Reactのまま。SSRへの対応を、そのままRSCの再実装と受け取らないようにしたいところです。
TransitionやActionは、名前だけで判断しない
RedactのstartTransitionとuseTransitionは処理を同期的に実行し、pendingは常にfalse。useDeferredValueも渡された値をそのまま返します。重い一覧の更新を後回しにして入力を優先する、というReactと同じ効果は得られません。
参考記事では、意図的に計算負荷を入れた商品一覧を両方のランタイムで比較しています。Redactでは配信サイズが小さくなる一方、入力の遅延が見られたと報告されています。これは特定のデモの結果ですが、「小さいから操作も必ず軽い」とは言えない理由が分かります。
フォーム周りにも確認が必要です。公式の互換表によると、useActionStateは初期状態と何もしないdispatch、falseを返し、Actionを実行しません。useOptimisticのsetterも何もしません。これらに処理を任せている画面では、importの差し替えだけで同じ動作になるとは考えない方がよさそうです。
nanoは、挙動を変えずに圧縮する設定ではない
標準のredact()はfullプリセットで、ネイティブアニメーションを除くオプション機能を有効にします。対してnanoはオプション機能をすべて無効にした状態から始め、必要な機能を個別に戻す設定です。
たとえばcontextを無効にするとProviderの値は伝わらず、読み取りはデフォルト値になります。hydrationを無効にした場合、hydrateRootは例外を投げます。nanoは単なる圧縮率の切り替えではありません。不要な機能を見極めて初めて使える選択肢です。
サイズを比べる際も測定対象を揃えたい。公式READMEの表はランタイムのバンドルであり、アプリ全体のサイズではありません。実際の削減量はtree shakingや使う機能で変わります。
試すなら、まず標準設定で既存画面の挙動を比べるのが堅実です。検索入力、フォーム送信、hydrationを確認し、配信量と操作中の応答性を別々に測る。その後で使わない機能を落とす順番なら、軽量化のために何を手放したかを追いやすくなります。