mcpField
R
rsc-data-optimizer

rsc-data-optimizer

github.com/julianromli開発21052 回インストール3 日前に更新
リポジトリ

rsc-data-optimizer について

rsc-data-optimizerは、React Server Componentアプリのデータ読み込みを改善する開発者向けスキルです。適切なクライアント側取得をサーバーレンダリングに移し、対話的なデータにはクライアントコンポーネントを残す方法を案内します。

主な機能

  1. 01クライアント側取得のアンチパターン確認
  2. 02サーバー・クライアントコンポーネントの選択
  3. 03対話的なセクションの切り出し
  4. 04データベースとフロントエンドの型変換
  5. 05ストリーミングとキャッシュのパターン案内

活用シーン

  1. 01クライアント側取得によるローディング表示の発見
  2. 02初期ページデータの取得をサーバーへ移行
  3. 03検索やページネーションをクライアント側に維持

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/julianromli/ai-skills --skill rsc-data-optimizer

インストール後、Claude Code で/rsc-data-optimizerを入力して読み込まれたか確認します。

同梱ファイルreferences/patterns.md

詳細

RSC データフェッチの最適化

遅いクライアントサイドのデータフェッチを、瞬時に表示されるサーバーサイドレンダリングに最適化します。

簡易診断

コードベース内で、次のアンチパターンを検索します。

# Find client-side fetching patterns
rg -n "useEffect.*fetch|useState.*loading|useStore\(\)" --type tsx
rg -n '"use client"' app/ --type tsx

注意すべき点:

  • "use client" + useEffect + fetch() = 初回読み込みが遅くなります
  • isLoading に対する useState(true) = ユーザーにスピナーが表示されます
  • 初期ページデータに対する useStore() または useContext = データ取得のウォーターフォールが発生します

3 ステップの変換ワークフロー

ステップ 1:データ要件を特定する

初回レンダリング時にページが必要とするデータを確認します。

  • 静的、または変更頻度の低いデータ → サーバーコンポーネント(SSR)
  • ユーザーが操作するデータ(フィルター、検索) → クライアントコンポーネント
ステップ 2:インタラクティブなセクションを切り出す

useInView、useState、onClick を使うセクションを、別のクライアントコンポーネントに移動します。

// components/data-section.tsx
"use client";

interface DataSectionProps {
  data: Item[];  // Receive data as props
}

export function DataSection({ data }: DataSectionProps) {
  const [ref, inView] = useInView();  // Client-side animation OK
  return <div ref={ref}>...</div>;
}
ステップ 3:ページをサーバーコンポーネントに変換する
// app/page.tsx - NO "use client"
import { getData } from "@/lib/actions/data";
import { DataSection } from "@/components/data-section";

export default async function Page() {
  const data = await getData();  // Fetch on server
  return <DataSection data={data} />;
}

型アダプターパターン

DB の型がフロントエンドの型と異なる場合:

import type { Item as DBItem } from "@/lib/database.types";
import type { Item } from "@/lib/types";

function adaptDBToFrontend(db: DBItem): Item {
  return {
    id: db.id,
    name: db.name,
    description: db.description ?? "",
    createdAt: new Date(db.created_at),
  };
}

export default async function Page() {
  const dbItems = await getItems();
  const items = dbItems.map(adaptDBToFrontend);
  return <ItemList items={items} />;
}

クライアントサイドを維持する場合

次の場合は "use client" を維持します。

  • リアルタイムサブスクリプション(Supabase realtime)
  • ユーザー操作によって開始されるフェッチ(検索、フィルター、ページネーション)
  • クライアントの状態に依存するデータ(認証トークン、localStorage)
  • 無限スクロール/追加読み込みのパターン

高度なパターン

references/patterns.md を参照してください。

  • 並列データフェッチ
  • Suspense を使ったストリーミング
  • エラーバウンダリ
  • キャッシュ戦略
  • SSR とクライアントを組み合わせたパターン

コメント