Server Component

서버 컴포넌트 경계

App Router에서는 컴포넌트가 기본적으로 서버에서 실행된다. 이 기본값을 살리면 번들 크기와 보안 경계가 좋아진다.

01서버에서 끝낼 일

DB query, markdown 읽기, 권한 검사, 비밀 API 호출은 서버 컴포넌트에서 처리한다.

02상호작용 분리

클릭, 입력, focus처럼 브라우저 상태가 필요한 부분만 client component로 분리한다.

03props 경계 검증

Date, function, class instance처럼 직렬화가 애매한 값을 client child로 넘기지 않는다.

Bundle

브라우저 JS 감소
서버 컴포넌트 자체는 클라이언트 번들에 포함되지 않는다.

client child 의존성은 포함된다.
Secret

서버 전용 접근
환경 변수와 DB client를 브라우저로 보내지 않고 처리한다.

import 방향을 지킨다.
Async

서버 데이터 준비
컴포넌트에서 await로 데이터를 준비할 수 있다.

waterfall을 조심한다.
경계

client로 내려가는 선
client component가 import하는 하위 트리는 클라이언트 번들 후보가 된다.

경계는 낮게 둔다.

use client · 직렬화 · 비밀 점검

use client

서버에서 처리 가능한 컴포넌트에 불필요하게 붙어 있지 않은가.

직렬화

client child에 함수나 비직렬화 객체를 props로 넘기지 않는가.

비밀

서버 전용 모듈이 client component에서 import되지 않는가.

export default async function ProductPage() {
  const product = await db.product.findFirst();
  return <ProductView product={product} />;
}