Velog와 비슷한 블로그 프로젝트: 성능 개선 및 점검

derek·2024년 10월 16일
0

블로그 프로젝트 빌드 및 캐싱 최적화

cache

내가 만든 블로그 프로젝트를 빌드해 보았습니다. 대부분의 페이지는 정적으로 생성되었고, 다이나믹한 페이지는 서버사이드 렌더링을 통해 생성된 것을 확인할 수 있습니다.

fetch를 사용하면 Next.js가 동일한 요청에 대해 중복 제거를 수행하여 요청 수를 줄여줍니다. 그러나 fetch를 사용하지 않는 함수는 이러한 중복 요청을 처리하지 못합니다.

그 예시로, 프로젝트에서 서버에 있는 파일을 접근하는 함수에 console.log를 추가하고 빌드해 보았습니다.

아래와 같이 총 6번의 console.log가 호출되는 것을 확인할 수 있었습니다. 여러 페이지를 생성하다 보니 여러 페이지에 걸쳐 호출되거나 한 페이지에서 여러 번 호출된 것입니다.

현재는 빌드 시점에서 호출되므로 문제가 없을 수 있지만, 서버사이드 렌더링 중 여러 번 호출되면 여러 번 데이터를 읽어오는 문제가 발생할 수 있습니다. 따라서 데이터베이스에 접근하거나 파일을 읽어올 때는 자동으로 중복 방지가 되지 않기 때문에, React의 캐시 기능을 활용하는 것이 좋습니다. 사용법은 다음과 같습니다.

// service/posts.ts
const getAllPosts = cache(async (): Promise<Post[]> => {
  const filePath = path.join(process.cwd(), "data", "posts.json");
  const data = await fs.readFile(filePath, "utf-8");
  const posts: Post[] = JSON.parse(data);

  console.log("getAllPosts called");

  // 게시물을 최신순으로 정렬함
  return posts.sort((a, b) => (a.date > b.date ? -1 : 1));
});

지금 예시로 든 함수는 인자를 받지 않지만, 동일한 인자로 호출되면 캐시된 값을 반환합니다. 중요한 점은 서버가 동작하는 모든 시간에 캐시되는 것이 아니라, 한 번 렌더링되는 사이클에 한해서만 캐싱이 적용된다는 것입니다. 즉, 동일한 페이지에서 여러 번 호출할 때 캐싱이 이루어집니다.

이렇게 개선한 후 다시 빌드해 보니 console.log 호출 수가 4번으로 줄어들었는데요! 지금은 효과가 크지 않지만, 나중에 규모가 큰 프로젝트에서 로딩 속도를 현저히 줄일 수 있을 것으로 보입니다.

캐싱에 대한 더 깊이 있는 정보는 Next.js 공식 문서를 참고하세요.

generateStaticParams

마지막으로, 다이나믹 라우트에 해당하는 모든 부분은 서버사이드 렌더링이 될 예정입니다. 자주 방문하는 페이지를 미리 만들어 놓고 싶다면, 내가 원하는 slug에 대해 미리 생성할 수 있는 generateStaticParams를 사용하면 됩니다.

// posts/[slug]/page.tsx
export async function generateStaticParams() {
  const posts = await getFeaturedPosts();
  return posts.map((post) => ({
    slug: post.path,
  }));
}

아래와 같이 5개의 페이지가 미리 생성된 것을 확인할 수 있습니다. 즉, 해당 함수를 이용하여 자주 보는 포스팅에 대해 사용자들을 더 빠르게 접근시킬 수 있습니다.

profile
derek

0개의 댓글