Next.js의 SSG (Static Site Generation), SSR (Server-Side Rendering)을 하는 이유 및 사용법

김수근·2022년 8월 8일
4

SSG, SSR 자주 접하고 어렴풋이 개념은 알고 있던 내용이었는데 NextJS를 사용하게 되면서 좀 더 디테일하게 내용을 살펴 보았습니다.

SSR(server-side-rendering)이란?

SSR은 서버에서 사용자에게 보여줄 페이지를 모두 구성하여 사용자에게 페이지를 보여주는 방식입니다. SSR을 사용하면 모든 데이터가 매핑된 서비스 페이지를 클라이언트(브라우저)에게 바로 보여줄 수 있습니다.서버를 이용해서 페이지를 구성하기 때문에 클라이언트에서 구성하는 CSR(client-side rendering)보다 페이지를 구성하는 속도는 늦어지지만 전체적으로 사용자에게 보여주는 콘텐츠 구성이 완료되는 시점은 빨라진다는 장점이 있습니다.

SSG(static site generation)이란?

개발자가 빌드 시 사전생성페이지(pre-render page)를 만들어 static 페이지로 가지고 있게 됩니다. 클라이언트에서 페이지 요청 시 사전생성페이지를 로드하여 보여 줍니다. 페이지를 사전 생성하여 가지고 있기 때문에 클라이언트 요청에 대한 응답이 빠릅니다. 빌드 할 때 페이지가 생성되므로 변경사항이 생기게 되었을 때는 next.js의 특정 함수를 활용하여 변경사항을 읽은 다음 페이지를 생성 합니다.

SEO( search engine optimization )

SEO(검색 엔진 최적화)는 웹사이트가 검색 결과에 더 잘 보이도록 최적화하는 과정입니다.
검색 엔진은 웹을 크롤링 하면서 페이지에서 페이지로 링크를 따라가고, 찾은 콘텐츠의 색인을 생성합니다. 검색 결과에 보이는 것은 바로 그 콘텐츠 색인입니다. 크롤러는 일정 규칙을 따르므로, SEO를 진행하며 해당 규칙을 밀접하게 따라가면 웹사이트가 검색 결과의 보다 높은 곳에 노출돼 (전자상거래와 광고라면) 수익으로 연결될 수도 있습니다.
검색 엔진은 일부 SEO 가이드라인을 제공하긴 하지만 대형 검색 엔진의 경우 결과 랭킹은 영업 비밀로 취급합니다. 따라서 SEO는 검색 엔진의 공식 가이드라인에 더해 경험적인 지식, 논문과 특허 등에서 가져온 이론적 지식을 결합한 과정입니다.

SSG, SSR를 사용하는 이유

사전 렌더링한 페이지는 컴포넌트가 첫 번째 렌더링 사이클을 마친 후의 스냅샷을 콘텐츠로 가지고 있습니다. 어떤 요청이 전달되면 라우터를 통해서 페이지로 이동 되고 사전 렌더링 페이지가 반환됩니다.

[ 요청 → 라우팅처리 → 사전렌더링 페이지 ]

사전 렌더링페이지를 React가 받아가서 페이지에 Hydrate 작업( SPA 생성 및 제어 )을 수행합니다. 이 과정에서 useEffect등을 실행하거나 통신한 데이터를 받아와서 상태를 변경하여 페이지를 업데이트 합니다. 상태를 변경하고 업데이트를 진행 하는 것은 서버나 사전 렌더링 페이지가 아닌 브라우저에서 실행 됩니다.

[ 사전렌더링 페이지 → 리액트에서 Hydrate 작업 수행 → 웹 페이지 업데이트 ]

사전에 렌더링된 페이지는 리액트가 작업한 페이지를 반영하지 못하고 있기 때문에 웹 소스 코드에 반영되어 있지 않습니다. (개발자 도구창 열어서 소스확인)

사전 렌더링 페이지를 사용함으로써 SEO에 좋지만 어떤 통신이나 상태 변경에 의한 동작을 마친 경우에는 재 렌더링된 데이터가 페이지에 반영되어 있지 않아 오히려 SEO에 좋지 않은 결과를 가질수 도 있습니다.

이런 상황을 보완하기 위해 SSG, SSR을 사용합니다.

SSG 사용 ( with NextJS )

  • 페이지 컴포넌트가 사전렌더링 되는 시점은 애플리케이션을 빌드하거나 Next 프로젝트를 빌드하는 시점
  • 요청이 서버에 도달했을때 서버에서 즉각적으로 사전렌더링 페이지를 만들지 않습니다
  • 개발자가 빌드할 때 사전 렌더링 페이지를 만듭니다.
  • 그래서 사이트가 배포 되고나면 사전 렌더링한 페이지는 변경 되지 않습니다.
  • 사전 렌더링 페이지를 변경해야 한다면 빌드를 새로해서 재 배포를 해야 합니다.
  • 자주 바뀌는 페이지가 아닌 경우에 사용합니다.
  • pages 폴더 안에 있는 컴포넌트 파일에서만 사용가능 합니다
  • Static에 캐시되어 사용되기 때문에 빠른 응답이 가능합니다.

getStaticProps

  • 페이지에서 사용할 props를 준비하는 기능을 합니다.

  • promise를 반환합니다. ( NextJs는 promise가 해결될 때 대기합니다 )

  • 클라이언트 측에 절대 실행되지 않기 때문에 어떤 코드든지 실행이 가능합니다. ( 파일시스템, 데이터베이스 등… )

  • 컴포넌트 함수에서 사용할 props를 반환합니다. ( 반환값은 보통 props 프로퍼티를 설정하며 key이름은 반드시 props여야 합니다. 여기에서 반환되는 props가 컴포넌트 함수의 매개변수로 전달되어 사용됩니다.)

  • 소스 코드

    const Component = (props) => {
      return <List listData={props.listData} />;
    };
    
    export async function getStaticProps(){
      // fetch 통신처리 처리후 DUMMY_LIST을 가져왔다고 가정
      const DUMMY_LIST = fetch(...)
    
      return {
        props:{
          listData : DUMMY_LIST,
        }
      };
    }

getStaticPaths

동적페이지 사용 시 빌드하여 페이지가 사전 생성될 때 NextJS가 동적페이지의 모든 버전의 사전 생성이 필요합니다. 동적으로 생성되는 모든 페이지의 ID를 알아야 모든 페이지를 생성하는데 빌드 될 때 사전 생성되기 때문에 URL 기준으로는 값을 가져올 수 없습니다. 그래서 사전생성되지 않은 즉 식별 되지 않은 ID로 인식된 페이지는 404에러가 나타납니다. 이런 이유 때문에 동적페이지의 ID에 해당하는 객체를 반환하는 함수인 getStaticPaths를 선언 해야 합니다.

  • promise를 반환합니다
  • 모든 동적페이지의 ID 객체를 리턴하는 역할을 합니다
  • fallback, paths 속성을 반환 해야 합니다.
    • fallbck
      • NextJS에게 paths배열이 모든 지원되는 매개변수를 저장 할 지 아니면 일부만 저장할 지 알려주는 속성
      • false : 모든 지원되는 ID value를 포함하는 페이지 생성 ( path의 params에 지정된 값을 만족하는 페이지만 생성 )
      • ture : 요청이 들어오면 서버에서 동적으로 페이지 생성 ( 만족하는 값이 없더라도 페이지는 생성 )
    • path
      • params 속성을 가집니다.
  • 소스 코드
    export async function getStaticPaths(context) {
      return {
        fallback: false,
        paths: [
          {
            params: {
              pageId: 'list',
            },
          },
          {
            params: {
              pageId: 'read',
            },
          },
        ],
      };
    }


SSR 사용 ( with NextJS )

  • 페이지 컴포넌트가 사전렌더링 되는 시점은 정적 생성과는 다르게 배열 다음에 서버에서 실행됩니다.
  • 요청이 서버에 도달했을때 서버에서 즉각적으로 사전렌더링 페이지를 만들지 않습니다.
  • 요청이 들어올 때 마다 실행됩니다.
  • 데이터가 자주 변경되는 경우에 사용합니다
  • pages 폴더 안에 있는 컴포넌트 파일에서만 사용가능합니다
  • 응답, 요청에 대한 데이터가 필요할 때 사용하면 됩니다. (StaticGeneration은 요청, 응답객체에 접근 불가능)

getServerSideProps

  • nextJs는 사전 렌더링 중 getServerSideProps 함수를 발견하면 컴포넌트 함수 호출전에 getServerSideProps 함수를 먼저 호출 합니다.

  • 페이지에서 사용할 props를 준비하는 기능을 합니다.

  • promise를 반환합니다. ( NextJs는 promise가 해결될 때 까지 기다린다 )

  • 클라이언트 측에 절대 실행되지 않기 때문에 어떤 코드 든지 실행이 가능합니다. ( 파일시스템, 데이터베이스 등… )

  • revalidate는 없고 매개변수가 존재하는데 매개변수에는 요청객체, 응답객체가 있고 미들웨어에서 함께 작업 합니다. 요청객체를 통해 헤더와 바디에도 접근 가능합니다.

  • 헤더와 바디 접근이 가능해서 인증작업, 세션 쿠키를 할 때 도움이 될 수 있습니다.

  • 소스 코드

    const Component = (props) => {
       return <List listData={props.listData} />;
    };
    
    export async function getServerSideProps(context){
      const DUMMY_LIST = [{},{},...]
      
      const req = context.req; // 요청객체
      const res = context.res; // 응답객체
    
      return {
        props:{
          listData : DUMMY_LIST,
        }
      };
    }



참고 URL
https://developer.mozilla.org/ko/docs/Glossary/SEO

profile
✏️ 꾸준하게 기록하자

0개의 댓글