はじめに
「既視感がある」「vue の v-show みたいだ」と話題になっている <Activity>
ですが、
「そんな単純な機能を今更実装するのか?」と疑問に思いました。
調べてみると、基本的な使い方は似ていても 副作用の扱いや SSR 最適化など、設計思想がまるで違うことが分かりました。
この記事では、その違いを整理して皆さんにお伝えしていきます。
<Activity>
の基本挙動
コード例:表示/非表示の切り替え
// 従来の実装例
{isOpen && <Sidebar />}
// Activityを使用した実装例
<Activity mode={isOpen ? "visible" : "hidden"}>
<Sidebar /> {/* hiddenの場合、Sidebarが非表示に */}
</Activity>
<Activity>
は mode="hidden"
の場合に、内部で display: none
を付与して DOMを非表示にしています。
付加価値となる機能
1. 状態保持と高速な復元
従来の条件付レンダリングでは、要素を非表示にした時点でアンマウントされ、再表示時に初期化処理が毎回走ります。
これに対し、<Activity>
を使うと、非表示の間も状態と DOM を保持できるため、メニューの開閉などの UI 状態が維持され、再表示もスムーズに行えます。
2. 事前レンダリング
mode="hidden"
の要素も、最初のレンダリングで裏側では低優先度で描画されます。
- ユーザーが切り替えた瞬間に即座に表示可能
- Suspense 対応のデータフェッチやコード分割と相性が良い
- タブ UI で、裏タブのデータを先に取得しておくことでローディングを減らせる
3. SSR × セレクティブハイドレーション
セレクティブハイドレーションとは、SSRしたHTMLに対して、必要なコンポーネントから順に選択的にハイドレーションを進める仕組みを指します。
簡単に言うと、<Activity>
を境界として区切ることで、「軽いUI → 重いUI」の順に処理されるよう制御できます。
具体例として、次のようにタブを持つ画面で考えてみましょう
function Page() {
const [activeTab, setActiveTab] = useState('home');
return (
<>
<TabButton onClick={() => setActiveTab('home')}>
Home
</TabButton>
<TabButton onClick={() => setActiveTab('video')}>
Video
</TabButton>
<Activity mode={activeTab === 'home' ? 'visible' : 'hidden'}>
<Home />
</Activity>
<Activity mode={activeTab === 'video' ? 'visible' : 'hidden'}>
<Video />
</Activity>
</>
)
}
通常、Reactはページ全体を一度にハイドレートする必要があるため、Home
または Video
のレンダリングが遅い場合、ハイドレート処理中にタブボタンが反応しなくなる可能性があります。
この問題は、 <Activity>
境界として用いることで、Home/Video
のハイドレーションの優先度を下げ、タブボタンを先にハイドレートして応答性を確保する形で回避できます。
ここで重要な点は、条件付レンダリングを使用しない場合でも有効 だということです。
function Page() {
return (
<>
<Post />
<Activity>
<Comments />
</Activity>
</>
);
}
常時表示の領域でも、<Activity>
で囲むだけで「この塊は分離してハイドレート可能」というヒントになり、ページロード中の操作の体感速度が上がります。
v-show と <Activity>
の比較
上記を踏まえて、Vue の v-show
と React の <Activity>
の機能を対比してみます。
項目 | Vue v-show
|
React <Activity>
|
---|---|---|
DOM の扱い |
display: none を付与 |
display: none を付与 |
状態保持 | 保持する | 保持する |
副作用の扱い | 非表示でも実行される(ライフサイクルに依存) | 非表示の場合は停止する |
事前レンダリング | なし | hidden 状態でも低優先度レンダリング(表示前に準備可能) |
SSR 最適化 | なし | セレクティブハイドレーションで段階的に処理可能 |
いつ使うべきか?
- タブ UI / モーダル / 折りたたみ
- 状態を保持したい場面に有効
- 裏で次に表示しそうなコンテンツを事前に準備したい場合
- Suspense と組み合わせて「データ取得」を先行
- (
mode="hidden"
は 副作用が停止される点に注意 )
- 一部コンポーネントが重く、初期操作の応答性を守りたい場合
- ハイドレーションやレンダリングの優先度を下げる
まとめ
-
<Activity>
は「表示切替」+「副作用の休止/再開」+「ハイドレーション分割(Selective Hydration 参加)」の3点で価値がある - hidden 初期化は「次に見えそうなUI」を先回りで温める強力な手段
- SSR の見た目はそのままに、体感速度(最初に触るUIの反応性)を大きく改善できる
<Activity>
は使い方こそシンプルですが、v-show
の単なる表示制御とは異なり、状態保持・副作用制御・ハイドレーション最適化まで担う仕組みでした。
今後のフロントエンド最適化の定番手段になる可能性が高いので、ユースケースを見極めつつ積極的に活用していきましょう!