CSR, SSR, SSG, ISR (Feat. Next.js14)

j_wisdom_h·2024년 2월 26일
0

Next.js 프로젝트

목록 보기
5/8
post-thumbnail
💡 SPA를 CSR(Client Side Rendering) 방식으로 렌더링한다고 말한다. (단, SPA 방식이 모두 CSR인 것은 아니다.) MPA를 SSR(Server Side Rendering) 방식으로 렌더링한다고 말한다.

Client Side Rendering (CSR)

  • HTML 렌더링이 클라이언트(사용자의 브라우저)에서 실행되는 방식이다.
  • 사용자가 웹 사이트에 방문하면 브라우저는 서버에 HTML,CSS,Javascript 같은 리소스들을 요청한다.
  • 서버는 빈 뼈대의 html과 js를 건네주고 브라우저는 이 파일들을 파싱하여 렌더링한다.

Server Side Rendering (SSR)

  • HTML 렌더링을 서버에서 실행되는 방식이다.
  • 서버는 이미 렌더링 된 HTML 파일을 브라우저에게 전달한다.

Static-Site Generation (SSG)

  • 정적 사이트 생성의 약자로 사전 렌더링이라고도 한다.
  • SSG는 SSR과 다르게 빌드 시점에 렌더링한다. 빌드 시점에 정적 페이지를 한 번 렌더링을 하기 때문에 요청이 들어오면 만들어 놓은 HTML 문서를 응답해 준다.
  • 미리 생성된 페이지를 제공하는 방식 이기 때문에 페이지 내 데이터가 변화하더라도 변화된 내용들을 전혀 제공해주지 못한다.
💡 SSR : 페이지는 각 사용자 **요청**에 대해 **서버에서 동적으로 렌더링**된다. 서버는 최신 데이터를 통합하여 즉시 HTML을 생성하고 이를 클라이언트에 보낸다.

💡 SSG: 페이지는 사용자 요청과 관계없이 빌드 프로세스 중에 사전 빌드됩니다. 서버는 미리 HTML 페이지를 생성하고, 생성된 파일은 정적 자산으로 제공됩니다.

Incremental Static Regeneration (ISR)

💡 ISR증분 정적 재생은 **런타임** 중에 **정적 페이지**를 만들거나 업데이트 수 있도록 해주는 `SSG`과 `SSR`의 하이브리드 솔루션이다.

Next.js에서 제공하는 기능이기도 하며, 전체 사이트를 다시 빌드할 필요없이 페이지별로 정적 생성을 사용할 수 있게 해준다.

Next.js allows you to create or update static pages after
you’ve built your site. Incremental Static Regeneration (ISR) 
enables you to use static-generation on a per-page basis, 
without needing to rebuild the entire site. 
With ISR, you can retain the benefits of static while scaling to millions of pages.

즉, 정적생성으로 미리 만들어놓은 사이트들도 필요하다면 업데이트가 가능하다.

Next.js 12 → Next.js 13 달라진 점 (App router, Data fetching)

💡 Next.js 13의 앱 라우터에서는 `getStaticProps`를 지원하지 않는다**

The new data fetching in Next.js 13 is built on top of the fetch() Web API and akes use of async / await in Server Components.

Now, instead of using getServerSideProps() and getStaticProps()all fetched data is static by default, meaning it's rendered at build time.

Next.js 13에서 데이터를 가져오는 새로운 방식은 fetch 웹 API 위에 구축되었고, 서버 컴포넌트에서 async/await을 사용한다.

이제 getServerSideProps와 getStaticProps를 사용하는 대신, 가져온 모든 데이터는 기본적으로 정적이며, 빌드 시에 렌더링된다.

💡 빌드 시에 렌더링하면 실시간으로 변경되는 데이터들은 데이터를 업데이트 못하지 않나? fetch의 옵션으로 해결!

fetch 옵션 객체를 확장해서 각 요청마다 자체 캐싱 및 재검증 규칙을 설정할 수 있도록 한다.

  • {next: revalidate} 옵션을 사용하면, 정적인 데이터를 설정된 간격으로 새로고침하거나 백엔드에서 변경이 있을 때마다 새로고침 할 수 있다.
  • 자주 변경되는 데이터나 사용자와 관련된 동적인 데이터의 경우, fetch 요청 시에 {cache: no-store} 옵션을 사용할 수 있습니다.

➡️ 정리하면, 이전에 쓰던 서버 사이드 API 대신에 fetch()를 사용하면 되고, fetch의 옵션 객체를 이용해 이전의 서버 사이드 API와 같은 기능을 하게 할 수 있다.

  • { cache: 'force-cache' } : 캐시를 강제한다는 뜻으로 정적 사이트(SSG)로 만든다. (getStaticProps 대체)
  • {next: { revalidate: 10 }} : 10초마다 캐시를 갱신한다는 뜻으로 10초 후에 새로운 요청이 오면 페이지를 새로 생성한다. (revalidate 옵션이 있는 getStaticProps 대체[ISR])
  • { cache: 'no-store' } : 모든 요청에서 최신 데이터를 받아온다. 즉, 항상 서버 사이드 렌더링한다. (getServerSideProps 대체)

Data Fetching: Fetching, Caching, and Revalidating

Functions: fetch

[13 이전 버전 ]

function Blog({ posts }) {
  return (
    <ul>
      {posts.map((post) => (
        <li key={post.id}>{post.title}</li>
      ))}
    </ul>
  )
}

/*getStaticPaths*/
export async function getStaticPaths() {
  const res = await fetch('https://.../posts')
  const posts = await res.json()

  const paths = posts.map((post) => ({
    params: { id: post.id },
  }))
  return { paths, fallback: 'blocking' }
}

/*getStaticProps*/
export async function getStaticProps() {
  const res = await fetch('https://.../posts')
  const posts = await res.json()

  return {
    props: {
      posts,
    },
    revalidate: 10, 
  }
}

export default Blog

getStaticPaths

build 시간에 정적 생성할 경로들을 getStaticPaths 를 이용해 전달 받는다.

 fallback: 'blocking' 옵션은  build 시간에 만들어지지 않은 경로는 SSR처럼 요청시 새롭게 생성된다는 의미이다.

Functions: getStaticPaths

getStaticProps

해당 경로들에 대해서만 정적생성을 진행한다. 여기서 revalidate: 10 옵션이 추가되어 있는데, 이는 해당 페이지로 어느 사용자가 진입한 이후 10초 후에 해당 페이지에 대해서 정적생성을 진행한다는 의미이다. 이때 정적 생성된 페이지를 통해 다음 사용자에게 업데이트된 내용이 제공된다.

revalidate: 60 의 경우 

Untitled

ISR 동작 방식

  1. 사용자가 웹 페이지를 방문하면(request), 요청에 의해 페이지가 생성되지만 데이터가 오기를 기달려야하는 SSR과 달리 즉시 대체 페이지(fallback page)가 제공된다. 이 단계에서 대부분 placeholder 및 스캘래톤을 표시한다.
  2. 데이터가 확인되면 최종 페이지가 캐시되고, 사용자는 SSG와 마찬가지로 캐시된 버전의 페이지를 받게 된다.
  3. 재검증시에도 사용자는 먼저 캐시된 버전을 받고 업데이트된 버번을 받는다. (캐싱 전략: Stale-while-revalidate) : 오래된 페이지 재생성 및 재구축

ISR 장점

SSR과 달리 페이지가 즉시 제공되며(fallback page), 빠른 경험으로 사용자 경험도 좋아진다.

ISR 단점

페이지 디자인에 따라 첫번째 의미있는 페인팅을 지연시킬 수도 있다.

CSR vs SSR vs SSG

Data Fetching: Fetching, Caching, and Revalidating

NextJS와 ISR

요약

  • next.js는 backend에서 application 을 pre-render 함

  • non interactive 한 HTML 파일로 바꿈

  • 사용자가 웹사이트에 도착하면 HTML 전달

  • 프레임워크와 React.js를 initialize

  • use client 명령어를 가진 component가 hydrate 됨 (interactive)

  • hydration은 우리가 받은 HTML 위에서 React application을 실행한다는 뜻

    • eventListeners를 추가하고 , interactive 하게 만듦
    • HTML을 실제 interactive한 React Component로 -
    • 이점은 사용자들이 다운받아야 하는 자바스크립트 코드의 양이 줄어듦
  • SSR 과 SSG는 pre-rendering이라고도 불림

    • 추가 데이터의 fetching 과 react 컴포넌트의 HTML로의 변환이 렌더링 결과물이 클라이언트에게 전송되기 전에 발생
  • next.js에서는 기본적으로 모든 페이지를 미리 렌더링

  • 사용자의 기기에서 가 모든 일을 처리하는 대신 서버에서 먼저 HTML 파일을 생성하기 때문에, 렌더링 작업이 진행되는 동안 사용자에게 해당 페이지에 필요한 HTML 화면이 보여진다

  • 클라이언트가 받는 웹페이지는 단순히 웹 화면을 보여주기 위한 HTML 일 뿐이고, 동작에 필요한 JS 요소는 없음

  • 특정 JS 모듈 뿐 아니라 단순 클릭과 같은 이벤트들이 각 웹 페이지의 DOM 요소에 적용되어 있지 않은 상태의 페이지가 전송

  • Next.js 서버에서는 Pre-Rendering 된 웹 페이지를 클라이언트에게 보낸 뒤, 바로 React가 번들링 된 JS 코드들을 Chunk 단위로 클라이언트에게 전송한다.

  • 그리고 이러한 JS 코드들이 이전에 전송된 HTML DOM 요소 위로 리렌더링 되는 과정 속에서 자기 자리를 찾아 매칭된다.

  • 이러한 과정을 "Hydration"이라 부른다!

profile
뚜잇뚜잇 FE개발자

0개의 댓글