[Next.js 블로그 만들기] - (10)

generateStaticParams로 퍼포먼스 개선하기

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

YEAHx4

YEAHx4

2025-03-28

예전에 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>
  );
}

이상태로 빌드를 해 봅시다. 예전 버전에서 빌드를 하면 다음과 같이 나왔었습니다.

예전 빌드 결과

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

SSG 빌드 결과

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

Vercel 로그

성능 측정

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

lighthouse 결과

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