Next.js - Page Router (3) - SSR, SSG, ISR

크롱·2025년 1월 31일
0

Next.js

목록 보기
13/20

서버 사이드 렌더링 SSR

  • Next.js 의 다양한 사전 렌더링 방식 중에 가장 기본적인 렌더링
  • 브라우저에 접속 요청이 들어올 때 마다 사전 렌더링 진행 : 페이지 내부 데이터가 항상 최신 버전으로 유지

getServerSideProps

⚡ getServerSideProps 처럼 Next.js 에서 약속된 이름의 함수를 만들어서 export하면 해당 페이지는 이제 SSR로 동작하도록 자동 설정됨


export const getServerSideProps = () => {
 🟦 getServerSideProps는 밑 Home 페이지 컴포넌트보다 먼저 실행됨. 
 🟦 컴포넌트에 필요한 데이터를 불러오는 함수
  
return { // 반드시 props라는 개체 프로퍼티를 포함하는 하나의 객체 return
    props: { 
      data,
    },
  }
  
}
                             //{data} 
export default function Home(props: InferGetServerSidePropsType<typeof getServerSideProps>) {
  📝 이 페이지도 두번 실행됨. 서버에서 한번 실행 -> 브라우저에서 한번 실행
  📝 사전렌더링위해 서버에서 컴포넌트 실행 - 터미널에 hi 출력
  📝 하이드레이션 과정에서 한번 더 컴포넌트 실행 - 콘솔에 hi 출력됨
  console.log('hi')
  
  // window.location ; -> 이런 코드 쓰면 서버에서 실행될때 오류뜸
 🔍 해결 -> useEffect 처럼 브라우저에서 실행되는 코드 안에 쓰면 된다

 


정적 사이트 생성 SSG

  • SSR의 단점을 해결하는 사전 렌더링 방식
  • npm run build 명령어로 빌드할때
    빌드 타임에 페이지를 미리 사전렌더링 해 둠 -> 이 과정이 오래걸리더라고 사용자 경험에는 영향X
  • 빌드 타임 이후에는 페이지를 새롭게 사전 렌더링 하지 않아서 매번 똑같은 페이지만 응답 -> 최신 데이터 반영은 어려움
  • 404 페이지처럼 아무런 설정을 해두지 않으면 기본적으로 SSG

getStaticProps

export const getStaticProps = async () => {


  const [allBooks, recoBooks] = await Promise.all([
    fetchBooks(),
    fetchRandomBooks(),
  ])
  return {
    props: { allBooks, recoBooks },
  }
}

export default function Home({
  allBooks,
  recoBooks,
}: InferGetStaticPropsType<typeof getStaticProps>) {

동적 경로

/book/[id] 처럼 동적 경로를 갖는 페이지에 SSG를 적용하려면 반드시 사전 렌더링 진행되기 전에 이 페이지에 존재할수있는 모든 경로들을 직접 설정하는 작업을 먼저 해야한다. getStaticPaths 를 사용!

getStaticPaths = == 1. 경로 설정
getStaticProps = == 2. 사전렌더링


Fallback

  • "blocking"

빌드 타임에 사전에 생성해 두지 않았었던 페이지까지 사용자에게 제공


기존 경로에 없던 페이지는 처음에 SSR 방식처럼 서버사이드에서 사전렌더링 하느라 느릴수도있지만 그 이후 요청에는 Next 서버에 저장되어서 빠르게 렌더링



  • true

위에 blocking은 서버사이드에서 사전렌더링될때 페이지 데이터가 크다면 로딩시간이길어질수있다는 단점이있는데, 이를 보완한게 true

Props가 없는 페이지: getStaticProps로부터 받은 데이터가 없는 페이지, 즉 아무런 데이터가 없음. 사용자는 긴 로딩시간 대신 일단 페이지라도 먼저 볼 수 있다 = fallback 상태

fallback 상태 : 페이지 컴포넌트가 아직 서버로 부터 테이터를 전달 받지 못한 상태

  • false
    설정된 경로에 없는 것들을 무조건 Not FOund 404 로 보냄


개발 모드에서 테스트

사전 렌더링 방식이 SSG든 SSR이든 요청이들어올때마다 계속해서 새롭게 페이지를 사전 렌더링 한다. 그래서 SSG 가 제대로 작동하는지 보려면 빌드 후 실제 프로덕션 모드에서 실행을 시켜보아야한다.



증분 정적 재생성 ISR

가장 강력한 사전 렌더링 방식

단순히 그냥 SSG 방식으로 생성된 정적 페이지를 일정 시간을 주기로 다시 생성하는 기술


👆 기존 ssg의 방식 - 최신 데이터 반영 어려움

시간 기반 ISR - 특정 시간 이후에 정적으로 생성된 페이지를 다시 새롭게 재생성하도록 설정

export const getStaticProps = async () => {
  const [allBooks, recoBooks] = await Promise.all([
    fetchBooks(),
    fetchRandomBooks(),
  ])
  return {
    props: { allBooks, recoBooks },
  🌟revalidate: 3,    => 3초 주기로 업데이트 되게🌟
  }
}


ISR 주문형 재 검증🌟

일단 위에 처럼 시간 기반 ISR 페이지가 사용될 수 없는 페이지는 매우많음
ex. 게시글 페이지 처럼 사용자의 행동에 따라 변하는 페이지
=> 요청 기반 ISR 페이지를 사용하자! 매우많이 사용됨

API Routes를 통해서 Revalidate 요청을 받으면 특정페이지를 다시 ssg 방식으로 재생성 하게끔

api/revalidate.ts

import type { NextApiRequest, NextApiResponse } from 'next'

export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse
) {
  try {
    await res.revalidate('/') // index페이지 경로를 revalidate요청보낼거야
    return res.json({ revalidate: true }) // revalidate 성공했다는 결과
  } catch {
    res.status(500).send('Revalidation failed')
  }
}

이렇게 api route 코드를 작성해주고

index.ts

export const getStaticProps = async () => {
  const [allBooks, recoBooks] = await Promise.all([
    fetchBooks(),
    fetchRandomBooks(),
  ])
  return {
    props: { allBooks, recoBooks },
  }
}

...

위 코드는 일반 ssg 코드랑 같지만
http://localhost:3000/api/revalidate로 접속하면
페이지가 다시 재생성 되는걸 확인할 수 있다

profile
👩‍💻안녕하세요🌞

0개의 댓글