name: rsc-data-optimizer description: | 通过使用React Server Components(RSC),将慢速客户端数据获取转换为快速服务器端数据获取,以优化Next.js App Router的数据获取。
适用场景:
- 用户报告初始页面加载缓慢,带有加载旋转器
- 页面使用useEffect + useState进行数据获取
- StoreContext/useStore模式导致瀑布式数据获取
- 需要改善SEO(内容不在初始HTML中)
- 将“use client”页面转换为服务器组件
触发词:“slow loading”, “optimize fetching”, “SSR data”, “RSC optimization”, “remove loading spinner”, “server-side fetch”, “convert to server component”, “data fetch lambat”, “loading lama”
RSC 数据获取优化器
优化慢速客户端数据获取,实现即时服务器端渲染。
快速诊断
在代码库中搜索这些反模式:
# 查找客户端获取模式
rg -n "useEffect.*fetch|useState.*loading|useStore\(\)" --type tsx
rg -n '"use client"' app/ --type tsx
红色标志:
"use client"+useEffect+fetch()= 慢速初始加载useState(true)用于isLoading= 用户看到旋转器useStore()或useContext用于初始页面数据 = 瀑布式数据获取
3步转换工作流
步骤1:识别数据需求
确定页面在初始渲染时需要什么数据:
- 静态/很少变化的数据 → 服务器组件 (SSR)
- 用户交互数据(筛选、搜索) → 客户端组件
步骤2:提取交互部分
将带有 useInView、useState、onClick 的部分移动到单独的客户端组件:
// components/data-section.tsx
"use client";
interface DataSectionProps {
data: Item[]; // 通过props接收数据
}
export function DataSection({ data }: DataSectionProps) {
const [ref, inView] = useInView(); // 客户端动画OK
return <div ref={ref}>...</div>;
}
步骤3:将页面转换为服务器组件
// app/page.tsx - 无 "use client"
import { getData } from "@/lib/actions/data";
import { DataSection } from "@/components/data-section";
export default async function Page() {
const data = await getData(); // 在服务器端获取
return <DataSection data={data} />;
}
类型适配模式
当数据库类型与前端类型不同时:
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实时)
- 用户触发的获取(搜索、筛选、分页)
- 数据依赖于客户端状态(认证令牌、localStorage)
- 无限滚动/加载更多模式
高级模式
参见 references/patterns.md 获取:
- 并行数据获取
- 使用Suspense的流式传输
- 错误边界
- 缓存策略
- 混合SSR + 客户端模式