Next.js의 렌더링 방식에는 서버 사이드 렌더링(SSR)과 정적 사이트 생성(SSG)라는 두 가지 핵심 렌더링 방식이 존재합니다(물론 두 개 말고 더 있음). 이 두 전략은 웹 애플리케이션의 성능, SEO, 사용자 경험을 크게 향상시킬 수 있습니다.
SSR은 페이지 요청이 들어올 때마다 페이지 요청이 들어올 때마다 서버에서 HTML, CSS, js 파일 및 데이터를 받아와서 페이지를 렌더링하는 방식입니다. Next.js에서는 getServerSideProps 함수를 사용해서 SSR을 구현합니다.
getServerSideProps는 페이지 컴포넌트가 렌더링되기 전에 서버에서 실행되는 함수입니다. 이 함수는 다음과 같은 특징을 가집니다.
export const getServerSideProps = async (context) => {
// API 호출, 데이터베이스 쿼리 등을 수행
const data = await fetchSomeData();
console.log('서버에서 실행됨'); // 브라우저에서 안보이고 서버 콘솔에 보임
return {
props: {
data,
},
};
};
export default function MyPage({ data }) {
// data는 이미 서버에서 불러온 데이터
return <div>{data}</div>;
}
그리고 getServerSideProps 함수는 context 매개변수를 통해 요청 정보에 접근할 수 있습니다.
export const getServerSideProps = async (context) => {
// 쿼리 파라미터 접근
const { q } = context.query;
// 요청 헤더 접근
const userAgent = context.req.headers['user-agent'];
const results = await searchData(q);
return {
props: { results, userAgent },
};
};
장점:
단점:
CSR은 브라우저가 서버에 HTML과 js파일을 요청한 후 로드되면, 사용자의 상호작용에 따라 js를 이용해 동적으로 렌더링 시킵니다.
정적 사이트 생성은 빌드 시점에 페이지를 미리 생성하는 방식입니다. Next.js에서는 getStaticProps와 동적 경로의 경우 getStaticPaths를 통해 SSG를 구현합니다.
getStaticProps는 빌드 시점에 실행되어 페이지에 필요한 데이터를 가져옵니다.
export async function getStaticProps() {
const posts = await fetchPosts();
return {
props: {
posts,
},
};
}
export default function Blog({ posts }) {
return (
<div>
<ul>
{posts.map(post => (
<li key={post.id}>{post.title}</li>
))}
</ul>
</div>
);
}
동적 경로(/posts/[id]와 같은 형태)를 사용하는 페이지에 SSG를 적용하려면 getStaticPaths 함수가 필요합니다.
export async function getStaticPaths() {
// 빌드 시점에 생성할 경로 목록 가져오기
const posts = await fetchPosts();
// 각 포스트의 id로 경로 생성
const paths = posts.map(post => ({
params: { id: post.id.toString() }
}));
return {
paths,
fallback: false, // 지정되지 않은 경로는 404 반환
};
}
export async function getStaticProps({ params }) {
// params.id를 사용하여 특정 포스트 데이터 가져오기
const post = await fetchPostById(params.id);
return {
props: { post },
};
}
export default function Post({ post }) {
return (
<div>
<h1>{post.title}</h1>
<p>{post.content}</p>
</div>
);
}
getStaticPaths의 fallback 옵션은 빌드 시점에 생성되지 않은 경로에 대한 처리 방식을 결정합니다.
빌드 시 지정한 경로만 접근 가능하고, 그 외의 경로는 404 페이지를 반환합니다.
return {
paths: [/* 미리 생성할 경로들 */],
fallback: false
};
지정되지 않은 경로로 요청이 들어오면 SSR처럼 서버에서 페이지를 생성합니다. 생성이 완료된 후에야 페이지가 클라이언트에 전달됩니다.
return {
paths: [/* 미리 생성할 경로들 */],
fallback: 'blocking'
};
지정되지 않은 경로로 요청이 들어오면 먼저 HTML만 있는 페이지를 반환하고, 백그라운드에서 데이터를 가져와 페이지를 완성합니다.
return {
paths: [/* 미리 생성할 경로들 */],
fallback: true
};
그리고 이 옵션을 사용할 때에는 useRouter의 router.isFallback을 활용하여 로딩 상태를 처리 할 수 있습니다.
if (router.isFallback) return "fallback 로딩중입니다.";
이렇게 로딩으로 한 번에 처리하지 않고 isFallback처리를 따로 하는 이유는
fallback이 완료되고나서도 진짜 오류가 발생해서 데이터를 불러오지 못할 경우에는 따로 표시를 하기 위해서입니다.
장점:
단점: