NexusRenderer
NexusRenderer
는 렌더링을 클라이언트에 위임하여 성능을 향상시킬 수 있는 서버 전용 컴포넌트입니다.
핵심 개념: 렌더링 위임 (Rendering Delegation)
사용자가 페이지 사이를 이동할 때, 다음 페이지에 필요한 데이터가 이미 클라이언트 캐시에 신선한 상태로 존재할 수 있습니다. 이 시나리오에서 서버가 데이터를 다시 가져오고 컴포넌트를 다시 렌더링하는 것은 TTFB(Time to First Byte)와 서버 비용을 증가시키는 중복 작업입니다.
NexusRenderer
는 서버에서 렌더링하기 전에 클라이언트의 캐시 상태를 확인하여 이 문제를 해결합니다. 만약 클라이언트가 필요한 definition
에 대한 신선한 데이터를 가지고 있다고 판단되면, 서버 렌더링을 건너뛰고 가벼운 플레이스홀더를 전송하여 클라이언트가 캐시된 데이터를 사용해 즉시 렌더링하도록 지시합니다.
Import
import { NexusRenderer } from 'next-nexus/server';
동작 방식
NexusRenderer
는 RSC 요청과 함께 전송되는 클라이언트 캐시 메타데이터(참고: NexusRuntime
)에 의존합니다. 제공된 definition
(들)을 이 메타데이터와 비교하여 캐시 신선도(revalidate
TTL 기준)를 확인합니다.
- 신선한 경우 (If fresh): 렌더링을 클라이언트에 위임합니다.
- 만료되었거나 없는 경우 (If stale or missing):
serverComponent
를 렌더링하고, 클라이언트를 하이드레이션하기 위해 필요한 서버 사이드nexus
호출을 트리거합니다.
사용법
NexusRenderer
에는 서버 버전과 클라이언트 버전의 컴포넌트를 모두 제공해야 합니다.
serverComponent
: 클라이언트의 데이터가 신선하지 않을 경우 서버에서 렌더링할 컴포넌트.clientComponent
: 클라이언트에서 렌더링할 컴포넌트. 보통 서버 컴포넌트와 동일한 컴포넌트이지만,'use client'
파일에서 다시 export된 것입니다.
단일 Definition 사용 시
// components/ProductListUI.tsx (서버 컴포넌트일 수 있음)
import type { Product } from '@/api/productDefinition';
const ProductListUI = ({ data, title }: { data: Product[]; title: string }) => (
<div>
<h2>{title}</h2>
<ul>{data.map(p => <li key={p.id}>{p.name}</li>)}</ul>
</div>
);
export default ProductListUI;
// components/client/ui.ts (클라이언트 사용을 위한 재-export)
'use client';
export { default as ProductListUIClient } from '@/components/ProductListUI';
// app/page.tsx (서버 컴포넌트)
import { NexusRenderer } from 'next-nexus/server';
import { productDefinition } from '@/api/productDefinition';
import ProductListUI from '@/components/ProductListUI';
import { ProductListUIClient } from '@/components/client/ui';
export default function Page() {
return (
<NexusRenderer
definition={productDefinition.list}
serverComponent={ProductListUI}
clientComponent={ProductListUIClient}
componentProps={{ title: '저희 제품들' }}
/>
);
}
여러 Definition 그룹 사용 시
definition
맵을 전달할 수도 있습니다. 이 중 하나라도 클라이언트에서 신선하다면, 렌더러는 렌더링을 위임합니다. 만료된 definition
들은 클라이언트가 필요한 모든 데이터를 가질 수 있도록 서버에서 백그라운드로 선패치(prefetch)합니다.
<NexusRenderer
definitions={{ products: productDefinition.list, stats: statsDefinition.summary }}
serverComponent={ServerGroup}
clientComponent={ClientGroup}
componentProps={{ title: '개요' }}
/>
중요 고려사항
- 하이드레이션 활성화 필수:
NexusRenderer
는 컴포넌트 트리 내에NexusHydrationBoundary
가 활성화되어 있어야 합니다. - 클라이언트 컴포넌트 Export:
clientComponent
는 반드시 상단에'use client'
지시어가 있는 파일에서 export되어야 합니다. - 서버 전용 API 금지:
NexusRenderer
에 전달되는 컴포넌트 내에서 직접 서버 전용 API(예: 데이터베이스 클라이언트, 파일 시스템 접근)를 사용하지 마세요. 해당 컴포넌트는 클라이언트에서 렌더링될 수 있습니다. 데이터는 컴포넌트 밖에서 가져와 props로 전달하세요.
함께 보기
Last updated on