Next.js 페이지 라우터

2025. 5. 1. 23:27Coding Study/Next.js

SSR 방식과 SSG 방식 사용법

SSR : Server Side Rendering

SSG : Static Site Generation

 

사용방법

 

컴포넌트 페이지에 getServerSideProps 함수를 사용사여 데이터를 전달하면  SSR 방식으로 작동

 

                             getStaticProps 함수를 사용하여 데이터를 전달하면 SSG 방식으로 작동

 

                             getStaticProps + fallback 옵션으로 사용시에는 아래와 같이 작동한다.

 

🔁 fallback 옵션 정리 (ISR과 함께 쓰이는 핵심 옵션)

✅ 사용 맥락

getStaticPaths를 사용하는 **동적 라우팅(static generation)**에서
어떤 경로를 빌드 시 미리 생성할지, 어떤 경로는 요청 시 새로 생성할지를 정하는 옵션


⚙️ 작동 메커니즘과 옵션 종류

1. fallback: false

  • 정의된 경로만 HTML로 미리 생성
  • 빌드 시 정의되지 않은 경로는 404 Not Found
  • 보안적이지만 유연성이 낮음
export async function getStaticPaths() {
  return {
    paths: [{ params: { id: '1' } }],
    fallback: false
  }
}

➡️ /id/1은 렌더링됨
➡️ /id/2 요청 시 404 반환

 

2. fallback: true

  • 빌드 시 정한 경로는 미리 생성
  • 그 외 경로는 접속 시점에 서버가 백그라운드에서 HTML 생성
  • 생성 중에는 로딩 화면 표시 필요
  • 이후 생성된 페이지는 캐시에 저장되어 다음 요청부터는 정적 파일처럼 작동

 

export async function getStaticPaths() {
  return {
    paths: [{ params: { id: '1' } }],
    fallback: true
  }
}

➡️ /id/2 요청 시에는

  1. 일단 로딩
  2. 서버에서 동적 생성
  3. 완료되면 사용자에게 응답
  4. 이후 정적으로 캐싱됨

3. fallback: 'blocking'

  • 클라이언트에게 로딩 없이 대기 시킨 후, 서버가 새 페이지 생성 완료 후 응답
  • 사용자 입장에선 처음부터 완성된 페이지를 받게 됨
  • SEO에 유리, UX도 깔끔
export async function getStaticPaths() {
  return {
    paths: [{ params: { id: '1' } }],
    fallback: 'blocking'
  }
}

➡️ /id/2 요청 시에는
서버가 백그라운드가 아닌 블로킹 방식으로 바로 생성 후 전달

 

📌 ISR + fallback 관계 요약

옵션 특징 초기에 없는 경로 처리 방식 UX 캐싱
false 완전히 정적 404 반환 -
true 동적 + 로딩 UI 필요 로딩 후 생성 ⏳ 필요
'blocking' 동적 + 완성본 응답 대기 후 완성된 HTML 응답

 

ISR 방식 사용법

 1) 일정시간 마다 서버에서 페이지를 새로 만든다.

    getStaticProps 함수에 revalidate : 4  라는 옵션을 적용하여 초단위로 적용

 

 2) 데이터가 업데이트가 되면 페이지를 새로 만든다. (on dement ISR 방식)

   - 게시글 수정이나 커뮤니티 사이트같은 경우에 일정시간마다 업데이트 되면 게시글 수정한 내용이 반영이 안되어

      렌더링 되는 문제가 있다.

   - 아래 함수가 작성된 주소로 요청을 보내면 revaldate: true 가 작동되어 서버에서 페이지가 재 생성된다.

export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse
) {
  try {
    await res.revalidate("/");           // revalidate 옵션에 루트 페이지를 넣어주면 된다.
    return res.json({ revalidate: true }); // revalidate : true 가 리턴되어 페이지 재생성
  } catch (err) {
    res.status(500).send("Revalidation Failed");
    console.log(err);
  }
}

 

 

⚙️ SSR / SSG / ISR 작동 방식 이해하기

Next.js에서는 페이지 렌더링을 서버에서 미리 처리한 뒤 클라이언트로 전달하는 사전 렌더링(Pre-rendering) 방식을 통해 초기 렌더링 속도와 SEO 성능을 향상시킨다.

🟩 1. SSR (Server Side Rendering)

🛠 작동 메커니즘

  1. 사용자가 페이지에 접속
  2. 브라우저가 Next.js 서버에 HTTP 요청
  3. 서버는 요청을 받을 때마다 getServerSideProps() 함수 실행
  4. 서버는 이 함수에서 백엔드 API 등 필요한 데이터를 가져옴
  5. 데이터를 포함한 HTML 페이지를 즉시 생성
  6. 브라우저에게 완성된 HTML 전달 → 화면 출력

📌 특징

  • 항상 최신 데이터 보장
  • 접속할 때마다 서버 리소스 소비
  • 응답 시간이 백엔드 상태에 따라 느려질 수 있음

 

🟦 2. SSG (Static Site Generation)

🛠 작동 메커니즘

  1. 개발자가 npm run build 실행
  2. getStaticProps() 함수가 빌드 타임에 한 번 실행
  3. 백엔드 API 등에서 데이터를 미리 가져옴
  4. HTML 파일을 정적으로 생성
  5. 이 HTML 파일은 빌드 이후 모든 요청에 재사용

📌 특징

  • 요청 시 서버 로직 없이 빠르게 응답
  • 변경이 적은 콘텐츠에 적합 (예: 블로그 글)
  • 최신 데이터 반영이 어려움 (정적이므로)

🟨 3. ISR (Incremental Static Regeneration)

🛠 작동 메커니즘

SSG의 단점을 보완하기 위해 만들어진 방식이다.

  1. 기본 작동은 SSG와 동일
  2. getStaticProps()에 revalidate: 60 등 유통기한(초 단위)을 설정
  3. 정적 페이지는 일정 시간 동안 재사용됨
  4. 유통기한이 지나면 다음 요청에서 백그라운드로 페이지 재생성
  5. 새로 생성된 페이지는 이후 요청에 사용됨

📌 on-demand revalidation

  • 사용자가 게시글 수정, 댓글 작성 등 특정 이벤트 발생 시
  • API 요청으로 즉시 페이지 재생성 요청 가능
// Next.js API 라우트 예시
res.revalidate('/posts/my-post')

 

 

 

SSR
(Server Side Rendering)
1️⃣ 브라우저 요청
2️⃣ 서버에서 getServerSideProps 실행
3️⃣ 실시간 데이터 요청 (API 등)
4️⃣ HTML 생성 후 응답
5️⃣ 클라이언트 Hydration 진행
✅ 필수 (모든 컴포넌트) - 항상 최신 데이터- SEO 최적화 가능 - 응답 속도 느릴 수 있음- 트래픽 증가 시 서버 부하- 모든 요청마다 재렌더링
SSG
(Static Site Generation)
1️⃣ npm run build 시점에
2️⃣ getStaticProps 실행
3️⃣ API 등으로 데이터 미리 가져옴
4️⃣ 정적 HTML 생성
5️⃣ 사용 시 즉시 응답
6️⃣ 클라이언트 Hydration 진행
✅ 필수 (정적 파일 + JS 연동) - 빠른 응답 속도- 서버 부하 없음- CDN 캐시 활용 용이 - 실시간 데이터 반영 어려움- 페이지 수 많을수록 빌드 시간 증가
ISR
(Incremental Static Regeneration)
📦 초기: SSG와 동일
🕒 이후:- 일정 시간(revalidate) 지나면- 요청 시 서버에서 HTML 재생성
🔁 또는 on-demand로 수동 재생성🎯 이후 캐시에 저장➡ Hydration
✅ 필수 (캐시된 페이지도 클라이언트에서 실행됨) - 빠른 응답 + 최신 데이터 보완- 페이지별 재생성 가능- 유연한 갱신 방식 - 최초 접속 시 느릴 수 있음 (fallback에 따라)- 구현 복잡도 ↑

 

 

 

🧩 비교 요약

렌더링 방식데이터 최신성초기 응답 속도서버 부하대표 함수

 

SSR ✅ 항상 최신 ❌ 느릴 수 있음 🔺 높음 getServerSideProps
SSG ❌ 고정됨 ✅ 매우 빠름 ✅ 낮음 getStaticProps
ISR 🔄 일정 주기 갱신 ✅ 빠름 ⚖️ 중간 getStaticProps + revalidate

 

 

 

✅ 페이지 라우터의 장점

1. 파일 시스템 기반의 간편한 라우팅

Next.js 페이지 라우터의 가장 큰 장점 중 하나는 폴더 구조만으로도 페이지 라우팅이 가능

  • /pages/index.tsx → 루트 페이지 (/)
  • /pages/search.tsx → /search 페이지
  • /pages/book/index.tsx → /book 페이지

추가적인 라우팅 설정 없이 폴더와 파일을 구성하는 것만으로 라우팅이 자동으로 처리된다

또한, 동적 라우팅도 매우 유연하게 지원한다.

  • [id].tsx → 하나의 URL 파라미터 대응 (/book/1)
  • [...id].tsx → 다중 중첩 URL 파라미터 대응 (/book/1/2/3)
  • [[...id]].tsx → 옵셔널 중첩 URL까지 대응 -->기존에는 들어갈수 없던 /book 이라는 url 에도 들어갈수 있다 

이처럼 폴더와 파일 구조만으로도 유연하게 다양한 라우팅 구성을 할 수 있는 점이 큰 장점


2. 다양한 방식의 사전 렌더링 지원

Next.js는 기존 React의 FCP 문제를 해결하기 위해 다양한 사전 렌더링(Pre-rendering) 방식을 제공한다.

- SSR (Server Side Rendering)

  • 접속 요청 시 매번 서버에서 새로 페이지 생성
  • 항상 최신 데이터를 반영 가능 👍
  • 하지만 백엔드 요청 지연 시 속도 저하 발생 가능 

- SSG (Static Site Generation)

  • 빌드 타임에 미리 페이지 생성
  • 정적 페이지이므로 응답 속도 매우 빠름
  • 그러나 빌드 이후 데이터 반영 불가

- ISR (Incremental Static Regeneration)

  • 정적 페이지 + 일정시간 후 페이지 업데이트
  • 일정시간 지난 후, 페이지 자동 재생성
  • 또는 onDemand 방식으로 수동 리밸리데이트 옵션 적용 가능

SSR, SSG, ISR 세 가지 방식을 상황에 맞게 조합하여 사용할 수 있어 다양한 요구 사항에 대응 가능하다


❌ 페이지 라우터의 단점

1. 페이지별 레이아웃 설정이 번거롭다

페이지마다 다른 레이아웃을 적용하려면 다음과 같은 절차가 필요하다.

  • getLayout() 메서드를 각 페이지마다 따로 작성
  • App 컴포넌트에서 레이아웃 로직을 조건부 처리

이러한 방식은 코드가 복잡하고 중복되기 쉬우며 유지보수에도 불리
(App Router에서는 이 문제가 크게 개선됩니다.)


2. 데이터 패칭이 페이지 컴포넌트에 집중됨

getServerSideProps, getStaticProps를 사용하면 서버에서 데이터를 가져와야 하는데, 이 데이터는 페이지 컴포넌트에만 props 형태로 전달

  • 자식 컴포넌트에서 이 데이터를 사용하려면 props 전달을 일일이 해야 함
  • 컴포넌트 구조가 깊어지면 매우 번거로움
  • 상태 관리 도구 (Context, Redux 등) 필요성이 증가

3. 불필요한 컴포넌트까지 번들에 포함

Next.js에서는 모든 React 컴포넌트가:

  1. 서버에서 먼저 렌더링 (Pre-render)
  2. 클라이언트에서 다시 실행 (Hydration)

이때 상호작용이 없는 단순 UI 컴포넌트들조차 번들에 포함되어 브라우저로 전달되며, 이는 다음과 같은 문제를 야기합니다:

  • 번들 크기 증가 → TTI(Time To Interactive) 지연

실제로 필요 없는 컴포넌트도 자바스크립트 실행 필요

 

 

 

💧 하이드레이션(Hydration)이란?

Next.js의 렌더링 구조에서는 초기 화면이 서버에서 HTML로 미리 렌더링되고, 이후 클라이언트 측에서 JavaScript를 연결하여 상호작용을 가능하게 만드는 과정을 **하이드레이션(Hydration)**이라고 부른다.

하이드레이션이 필요한 이유

  • 서버에서 사전 렌더링된 HTML은 정적인 콘텐츠일 뿐이다.
  • 여기에 React의 JavaScript가 연결되어야 버튼 클릭, 입력 처리 등 상호작용이 가능해진다.
  • 이 연결 작업이 바로 하이드레이션

🔧 이 과정이 끝나는 시점을 **TTI(Time to Interactive)**라고 부르고,
사용자가 페이지와 완전히 상호작용할 수 있게 되는 순간 이다.


하이드레이션의 문제점

페이지 라우터에서는 모든 컴포넌트가 무조건 하이드레이션 대상이 된다.

  • 상호작용이 전혀 없는 컴포넌트도 브라우저에서 한 번 더 실행됨 
  • 이로 인해 JavaScript 번들 크기 증가
  • TTI가 지연되고 성능 저하가 발생할 수 있음

예시로, 단순 UI 출력만 하는 컴포넌트는 사실 하이드레이션이 필요 없음에도 불구하고 번들에 포함된다.

 

 

'Coding Study > Next.js' 카테고리의 다른 글

Next.js 데이터 fetching  (0) 2025.05.13
Next.js 사전렌더링  (0) 2025.05.13