You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next 14.1 SSR场景下客户端数据持久化与导航优化方案

解决方案:优化SSR数据获取与缓存,提升子路由导航速度

1. 服务器端:配置合理缓存策略,减少重复请求

你之前用force dynamic和revalidate=0会完全禁用缓存,导致每次导航都重新请求Supabase。可以针对性调整缓存规则,平衡数据新鲜度和加载速度:

调整页面缓存有效期

在子路由page.tsx中设置revalidate,根据数据更新频率配置缓存时长(比如60秒,可按需调整):

// app/manage/[slug]/tenants/page.tsx
export const revalidate = 60; // 缓存60秒,到期自动重新拉取最新数据

export default async function Page({ params }: { params: any }) {
  const supabase = createClient();
  // 给Supabase请求添加缓存配置,利用HTTP缓存机制
  const { data: manager } = await supabase
    .from('managers')
    .select()
    .eq('slug', params?.slug)
    .single()
    .option({ cache: 'force-cache' });

  const properties = await getPropertiesWithEnvelope(manager);
  const tenantsData = await getTenants(manager);

  return <ManageComp tenantsData={tenantsData} properties={properties} manager={manager} />;
}

父路由预取共享数据

将manager、properties这类跨子路由共享的数据,放到父路由layout.tsx中统一获取,避免每个子路由重复发起相同请求:

// app/manage/[slug]/layout.tsx
export const revalidate = 60;

export default async function ManageLayout({
  children,
  params,
}: {
  children: React.ReactNode;
  params: { slug: string };
}) {
  const supabase = createClient();
  const { data: manager } = await supabase
    .from('managers')
    .select()
    .eq('slug', params.slug)
    .single()
    .option({ cache: 'force-cache' });
  const properties = await getPropertiesWithEnvelope(manager);

  // 将共享数据传递给所有子路由页面
  return (
    <div>
      {React.cloneElement(children as React.ReactElement, { manager, properties })}
    </div>
  );
}

子路由page.tsx可简化为:

// app/manage/[slug]/tenants/page.tsx
export const revalidate = 60;

export default async function Page({ manager, properties }: { manager: any; properties: any }) {
  const tenantsData = await getTenants(manager);
  return <ManageComp tenantsData={tenantsData} properties={properties} manager={manager} />;
}

2. 客户端:本地缓存快速初始化状态,后台更新

不用全局状态管理,可通过sessionStorage临时缓存数据,切换路由时先加载缓存数据渲染页面,再后台静默更新最新数据:

// app/manage/[slug]/tenants/ManageComp.tsx
export default function ManageComp({ properties, tenantsData, manager }: any) {
  const [progress, setProgress] = React.useState(0);
  // 优先从sessionStorage加载缓存数据,无缓存则用SSR传递的props
  const [tenants, setTenants] = React.useState<any>(() => {
    const cacheKey = `tenants_${manager.id}`;
    const cachedData = sessionStorage.getItem(cacheKey);
    return cachedData ? JSON.parse(cachedData) : tenantsData || [];
  });

  // 组件挂载后后台更新最新数据,不阻塞页面渲染
  React.useEffect(() => {
    const updateTenants = async () => {
      setProgress(50);
      const freshTenants = await getTenants(manager);
      setTenants(freshTenants);
      sessionStorage.setItem(`tenants_${manager.id}`, JSON.stringify(freshTenants));
      setProgress(100);
    };
    updateTenants();
  }, [manager.id]);

  const fetchTenants = async () => {
    setProgress(50);
    const freshTenants = await getTenants(manager);
    setTenants(freshTenants);
    sessionStorage.setItem(`tenants_${manager.id}`, JSON.stringify(freshTenants));
    setProgress(100);
  };

  // 原JSX代码保持不变
}

3. 优化数据获取逻辑:合并请求减少网络开销

如果getPropertiesWithEnvelope和getTenants内部包含多个独立Supabase请求,可以尝试合并为批量请求(比如用Supabase的rpc函数、批量查询),减少网络往返次数,降低整体请求耗时。


内容的提问来源于stack exchange,提问作者Gaston Jacinto

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 15:56:01