19. 동적 데이터를 랜더링하기 위한 전략
19. 동적 데이터를 랜더링하기 위한 전략

19. 동적 데이터를 랜더링하기 위한 전략

Authors
Date
Apr 26, 2025
Tags
Next.js
Published
Published
Slug
💡
이 글은 작성자의 견해를 바탕으로 chatgpt의 도움을 받아 작성되었습니다.
Next.js 14.2 버전을 기준으로 작성되었습니다.

🏗️ 들어가며

웹 애플리케이션에서 데이터를 효율적으로 로딩하는 방법은
그 데이터가 어떤 속성을 가지고 있는지에 따라 달라진다.
데이터가 정적이라면 빌드 시점에 페이지를 생성해도 무방하지만,
데이터가 시간에 따라 바뀌거나 외부 요인으로 계속 변화하는 경우라면
정적인 빌드만으로는 이를 적절히 반영할 수 없다.
이 글에서는 백엔드 서버가 존재하고, 데이터가 동적으로 변화하는 환경을 가정하고
Next.js 14에서 제공하는 dynamic rendering, loading.tsx, 그리고 staleTimes를 활용하여
데이터를 효과적으로 로딩하는 방법을 소개한다.
 

⏱️ 동적 데이터를 가져오는 간단한 예제

이번 글에서 설명할 예제는 현재 시간을 API를 통해 실시간으로 가져와 화면에 표시하는 페이지이다.
외부 API(https://timeapi.io)에서 한국 시간(Asia/Seoul)을 가져와,
페이지를 새로고침할 때마다 현재 시각이 반영되는 동작을 구현한다.
예제에서는 Next.js의 App Router 구조를 사용하며,
다음과 같은 세 가지 주요 기술을 조합한다:
  1. dynamic rendering을 통한 실시간 데이터 패칭
  1. loading.tsx를 통한 로딩 상태 표시
  1. staleTimes를 통한 캐시 제어
 

🚀 Dynamic Rendering이란?

Next.js에서는 페이지가 어떻게 렌더링될지를 설정할 수 있다.
그중 dynamic rendering은 페이지가 요청될 때마다
서버가 데이터를 새로 패칭하여 HTML을 생성하는 방식이다.
cache: 'no-store'를 사용해 fetch 요청을 구성하거나,
dynamic = 'force-dynamic'을 설정하여 dynamic rendering을 구현할 수 있다.
항상 최신 데이터를 받아올 수 있도록 했다.
export const dynamic = 'force-dynamic'; // 또는 const res = await fetch('api', { cache: 'no-store', });
 
이렇게 설정하면 Next.js는 해당 페이지를
빌드 시점이 아니라 요청 시점에 매번 새로 생성한다.
특히 데이터가 계속 변화하는 경우에 유용하다.
 

🌀 loading.tsx의 역할

서버가 데이터를 가져오는 동안 사용자에게 아무런 피드백이 없다면,
"멈춘 화면"처럼 보이거나, 화면 깜빡임이 발생할 수 있다.
이를 해결하기 위해 Next.js에서는 loading.tsx를 사용할 수 있다.
// time/loading.tsx export default function Loading() { return <div>loading...</div>; }
loading.tsx는 서버가 데이터를 패칭하는 동안 자동으로 렌더링된다.
이를 통해 데이터가 로딩 중임을 사용자에게 명확하게 알려주고, 페이지 전환 경험을 자연스럽게 만들어 준다.
 

🌿 왜 staleTimes가 필요한가?

Next.js 14에서는 실험적으로 **staleTimes**라는 옵션을 제공한다.
이는 서버에서 데이터를 fetch할 때, 그 결과를 얼마 동안 캐시에 저장할지를 설정하는 기능이다.
만약 staleTimes를 설정하지 않으면,
서버는 이미 패칭했던 데이터를 RSC 캐시에 저장해 두고
같은 요청에 대해서는 다시 fetch하지 않는다.
즉, 예상과 달리 데이터가 새로고침을 해도 갱신되지 않는 상황이 발생할 수 있다.
 
Next.js14 버전을 기준으로 dynamic rendering페이지는 30초, static rendering페이지는 5분의 staleTimes가 기본으로 설정되어 있다.
 
그러므로, 이 staleTimes설정을 변경하지 않는다면 페이지를 왔다갔다 하는 라우팅만으로는 새로운 데이터가 보이지 않는다.
💡
페이지를 새로고침한다면 새롭게 페이지가 랜더링되어 최신 데이터가 보인다.
이를 Hard Navigation 또는 Full page reload라고 부른다.
 
이를 해결하기 위해 staleTimes를 설정하면 다음과 같이 동작한다:
const nextConfig = { experimental: { staleTimes: { dynamic: 0, }, }, };
위와 같이 0초로 설정하면 해당 fetch 요청은 매번 stale 처리되므로
항상 fresh한 데이터를 패칭하게 된다.
만약 staleTimes를 1분으로 설정하면,
1분 동안은 이전 데이터를 재사용하고, 그 이후에만 새로 패칭한다.
 

⚡ 예제 흐름 요약

  1. 사용자가 /time 페이지로 이동한다.
  1. dynamic rendring으로 설정된 페이지가 서버에서 새롭게 렌더링된다.
  1. 데이터 패칭이 진행되는 동안 loading.tsx가 로딩 상태를 표시한다.
  1. staleTimes 설정을 통해 서버 캐시가 조정되며,
    1. 필요 시마다 최신 데이터를 받아올 수 있다.
 

예제

이곳에서 예제를 확인해보실수 있습니다