generateStaticParams로 퍼포먼스 개선하기
포스트 페이지를 SSG로 만들어 퍼포먼스를 개선합니다.

YEAHx4
예전에 CSS Rendering Blocking 줄이기라는 포스트에서 큰 CSS에 의해 발생하는 퍼포먼스 저하를 해결했었습니다. 그 이후로 나름 빨라지긴 했지만, 여전히 포스트를 열 때마다 살짝 대기시간이 있었습니다. 제 블로그는 포스트 페이지로 요청이 들어오면 파일을 읽는 요청을 보내 글 내용을 읽고, 그걸 렌더링하는 방식입니다. 이 과정에서 매 요청마다 파일을 읽고 다시 렌더링하는 과정에서 시간이 소요되었습니다. 하지만, 이 블로그는 동적으로 글을 추가하지도 않고 변경하지도 않기 때문에, 매 요청마다 항상 같은 응답을 보여줍니다. 그렇다면, 매번 새로 읽을 필요가 있을까요?
SSG
SSG(Static Site Generation)는 빌드 타임에 페이지를 정적(static)으로 생성하는 방식입니다. 매 요청마다 페이지를 새로 생성하지 않고 미리 생성해둔 하나의 페이지를 여러 번 응답에 활용해 시간과 리소스를 아낄 수 있습니다. 또, SEO에도 유리합니다. 저는 Next.js 15를 사용하고 있기 때문에 Next.js의 generateStaticParams
를 사용해 SSG를 구현하였습니다.
generateStaticParams
generateStaticParams는 Next.js 13에서 도입된 기능으로, return하는 페이지를 정적으로 생성할 수 있습니다.
export async function generateStaticParams() {
return posts.map((post) => ({
slugs: post.split("/"),
}));
}
저는 posts
에 모든 포스트의 경로가 모여있기 때문에 간단하게 처리할 수 있었습니다. 원래 컴포넌트는 딱히 건들 것 없이 generateStaticParams
만 추가해주면 됩니다.
export default async function Post(props: {
params: Promise<{ slugs: string[] }>;
}) {
const params = await props.params;
const { slugs } = params;
const content = await readContent(slugs.join("/"));
const toc = parseToc(content);
const { body, meta } = parsePost(content);
return (
<div className="flex justify-center gap-8">
<div className="max-w-64 w-full hidden xl:block" />
<div className="max-w-4xl w-full">
<PostBody
body={toHtml(body)}
meta={meta}
readingTime={Math.round(body.join("\n").length / 600)}
/>
</div>
<div className="max-w-64 w-full hidden lg:block">
<TableOfContent toc={toc} />
</div>
</div>
);
}
이상태로 빌드를 해 봅시다. 예전 버전에서 빌드를 하면 다음과 같이 나왔었습니다.

이제는 다음과 같이 나옵니다.

차이가 보이시나요? 페이지에 /posts/[...slugs]
밑에 여러 포스트 페이지들이 추가되었고, 맨 밑에 SSG가 추가되었습니다. 포스트 페이지들이 정적으로 생성되어 사용됨을 알 수 있습니다. Vercel에 배포하고, 포스트 페이지를 열어보면 다음과 같은 PRERENDER 로그를 볼 수 있습니다.

성능 측정
이제 구글 크롬의 Lighthouse를 통해 성능을 측정해 보겠습니다. 과거 CSS Rendering Blocking 줄이기에서 측정한 결과는 FCP(First Contentful Paint) 0.9s였습니다.

이번에 SSG를 적용한 후에는 FCP 0.3s로 0.6초가 줄어들었습니다. 이제는 포스트 페이지를 열 때마다 파일을 읽지 않고, 정적으로 생성된 페이지를 사용하기 때문에 체감 성능도 엄청나게 개선되었습니다.