Next

[Next] SSR / SSG / getStaticProps()

sian han 2023. 2. 20. 01:06

Next js 는 Node 에서 실행되기 때문에 웹브라우저에서 제공하는 전역객체 (window, document 등) 에 접근할 수 없다.

 

▶ 코드분할

코드분할이란 서로 다른 URL 에서 접근할 수 있는 여러 페이지로 분할하는 것이다.

이렇게 분할된 각 페이지는 응용프로그램에 대한 고유한 진입점이 된다.

Next.js 에는 코드분할을 지원하는 기능이 내장되어있다.

pages/ 디렉토리 내의 각 파일은 빌드 단계에서 자동으로 자체 자바스크립트 번들로 코드분할된다.

 ㄴ .. 이게 무슨말일ㄲ ㅏ?

 

pages 디렉토리

pages 디렉토리는 Next.js 에서 핵심적인 역할을 하는 디렉토리 중 하나로, 각 페이지에 대한 엔드포인트를 정의하는 역할을 한다. 즉 'pages' 디렉토리에 파일을 생성하면, 해당파일 이름에 맞는 경로로 라우팅이 가능해진다.

이런 페이지 파일들은 Reat 컴포넌트로 작성된다. 그래서 각 파일은 화면에 보여지는 페이지의 일부를 구성하는 코드를 포함하고 있다.

그리고 Next.js 는 이러한 페이지 파일들을 빌드 시점에 자동으로 서버사이드 렌더링을 위한 코드로 변환하여 클라이언트 요청이 있을 때마다 해당 페이지를 렌더링 할 수 있도록 한다.

 

Next.js 에서 애플리케이션을 빌드할 때 무슨일이 일어나는가 ?

Next.js 에서 애플리케이션을 빌드할 때, Next.js 는 코드를 빌드하여 배포 가능한 파일로 변환한다. 이때 Next.js 는 서버 측 코드와 클라이언트 측 코드를 모두 빌드한다. 그리고 빌드된 코드는 서버에 배포된다. 

 

빌드된 코드는 사용자가 사용할 준비가 된 프로덕션 최적화 파일이다. 이 파일은 코드가 최적화 되어있으며, 서버사이트 렌더링과 같은 기능이 가능한 상태로 빌드되며, 이 파일은 Next.js 서버에서 실행된다. 이렇게 빌드된 파일을 실행하면 Next.js 서버는 사용자의 요청에 따라 적절한 페이지를 렌더링하여 반환한다. 

 

렌더링이란 ?

React 작성한 코드를 해당 UI 에 대한 HTML 로 변환하기 위한 작업 단위가 있으며 이 프로세스를 렌더링이라고 한다.

렌더링은 서버 또는 클라이언트에서 발생할 수 있다. 

 

애플리케이션을 빌드할 때, Next.js 는 코드를 서버에 배포하고 사용자가 사용할 준비가 된 프로덕션 최적화 파일로 변환한다.

이 파일에는 다음과 같은 사항이 포함되어있다

  • 정적으로 생성된 페이지용 HTML 파일
  • 서버에서 페이지를 렌더링하기 위한 자바스크립트 코드
  • 클라이언트에서 페이지를 동적으로 만들기 위한 자바스크립트 코드
  • CSS 파일 

 

▶ Next.js 의 렌더링 유형

1. Pre-Rendering

2. 클라이언트 사이드 렌더링

3. 정적 사이트 생성

 

▷ ClientSide-Rendering

일반적인 React 애플리케이션에서 브라우저는 서버로부터 빈 HTML + UI를 구성하기 위한 JS 를 전달받는다.

초기 렌더링 작업이 사용자 장치에서 발생하므로 이를 ClientSide-Rendering 이라고 한다.

  - React 의 useEffect() 또는 useSWR 과 같은 데이터 페칭 훅을 사용해서 데이터를 가져오도록 선택해서 Next.js 애플리케이션의 특정 컴포넌트에 대해 ClientSide-Rendering 을 사용하도록 선택할 수 있다. 

 

 

▷ Pre-Rendering

반면 Next.js 는 모든 페이지를 Pre-Rendering 한다. Pre-Rendering 은 서버에서 DOM 요소들을 Build 하여 HTML 을 생성하는 것을 말한다.

 

ClientSide-Rendering 의 경우 렌더링 작업이 수행되는 동안 사용자에게 빈 페이지가 표시된다.

Pre-Rendering 의 경우 사용자는 완성된 HTML 을 볼 수 있다.

 

 

▶ Pre-Rendering 의 두가지 유형

Pre-Rendering 을 동적으로 해서 페이지를 생성하느냐, 정적으로 페이지를 생성하느냐 !

 

▷ 1. 서버사이드 렌더링 (SSR)

요청이 올 때마다 서버에서 HTML 을 생성하고,

페이지를 동적으로 만들기 위한 자바스크립트 명령이 클라이언트로 전송된다.

따라서 항상 최신 상태를 유지해야하는 웹페이지나, 분석차트 등 사용자의 요청마다 동적으로 페이지를 생성해 다른 내용을 보여주어야 하는 경우에 사용된다.

 

클라이언트에서 HTML 은 빠르고 정적인 페이지를 표시하는데 사용되는 반면, 

리액트는 JSON 데이터와 자바스크립트를 사용하여 컴포넌트를 동적으로 만든다.

이 과정을 하이드레이션(hydration)이라고 한다.

 

Next.js 에서는 getServerSideProps() 를 사용해 서버사이트 렌더링 페이지를 선택할 수 있다

getServerSideProps() 함수 안에 파라미터는 여러 정보를 받아올 수 있다.

 

 2. 정적 사이트 생성 (Static Site Generation)

SSG 는 빌드를 진행할 때 pages 폴더에서 작성한 각 페이지들에 대해 각각의 문서를 생성해서 static 한 파일로 생성한다.

해당 페이지에 대한 요청이 발생하게 되면, 이 페이지들을 재생성하는 것이 아닌 이미 생성된 페이지를 반환한다. 

따라서 생성이 완료되 HTML 문서를 재활용 하기 때문에 응답 속도가 매우 빠르다.

 

SSG 를 사용하면 HTML 이 서버에서 생성되지만, SSR 과 달리 런타임에 서버가 없다. 

콘텐츠는 애플리케이션이 배포될 때 빌드 때 (npm run build) 한번만 생성되며 HTML 은 CDN 에 저장되어 각 요청에 대해 재사용된다.

.. ??

⬇️

SSG에서는 HTML 파일이 서버에서 미리 생성되므로 런타임에는 서버가 필요하지 않다.

반면 SSR 은 서버측에서 동적으로 HTML 을 생성하는 방식이기 때문에 클라이언트 요청에 따라 서버에서 데이터를 가져와 HTML 을 생성하고 클라이언트에게 전달한다. 따라서 SSR 에서는 런타임에 서버가 필요하다. 

=> SSG 에서는 런타임에 서버가 없이 미리 생성된 HTML 파일을 사용해 클라이언트에게 전달되는 반면, SSR 에서는 런타임에 서버가 필요하고, 클라이언트 요청에 따라 HTML 이 동적으로 생성된다. 

 

Next.js에서 getStaticProps() 를 사용해 컴포넌트를 렌더링하기 전에 서버에서 데이터를 가져와서 props 로 전달할 수 있다.

getStaticProps() 

  • 서버측에서만 실행되는 함수이다.
  • 클라이언트 측에서 실행되지 않는다.
  • 빌드 시 딱 한번만 호출된다. => 다른 요청이 들어올 때마다 서버에서 데이터를 가져오는 것보다 훨씬 빠르다.
  • API 와 같은 외부데이터를 받아 Static Generation 하기 위한 용도이다.

블로그를 예로 들어보자.

서버에서 가져온 블로그 포스트 데이터를 사용해 '/posts' 페이지를 만들어보겠다.

 

먼저 getStaticProps() 를 사용해 서버에서 포스트 데이터를 가져온다.

// pages/posts.js

import React from 'react';

export default function Posts({ posts }) {
  return (
    <div>
      {posts.map(post => (
        <div key={post.id}>
          <h2>{post.title}</h2>
          <p>{post.body}</p>
        </div>
      ))}
    </div>
  );
}

export async function getStaticProps() {
  // 서버에서 포스트 데이터 가져오기
  const res = await fetch('https://jsonplaceholder.typicode.com/posts');
  const posts = await res.json();

  // 가져온 데이터를 props 객체에 추가하여 반환
  return {
    props: {
      posts,
    },
  };
}

위의 예제에서는 fetch() 함수를 사용해 포스트 데이터를 가져오고, 가져온 데이터를 props 객체에 추가해 반환한다.

그리고 Posts 컴포넌트에서는 props 를 받아와 포스트 데이터를 출력한다.

 

이렇게 했을 경우 '/posts' 페이지에 접속하면 서버에서 포스트 데이터를 가져와서 초기 렌더링 시에 보여준다.

getStaticProps() 함수를 사용하면 서버에서 데이터를 가져와서 초기 로딩 시간을 개선할 수 있다. 

 

getStaticProps() 함수를 사용하지 않았을 경우엔 ? 

getStaticProps()를 사용하지 않고 서버사이드 렌더링 방식으로 구현하면, 초기 렌더링 시에 사용자는 빈 화면을 먼저 보게 될 수 있다. 서버사이드 렌더링에서는 클라이언트 측 코드가 실행되기 전에 서버에서 페이지가 렌더링되고, 이후에 클라이언트 측 코드가 실행된다.

그리고 서버에서 페이지를 렌더링 할 때 데이터를 가져와서 페이지에 채운다. 데이터를 가져오는 시간동안 사용자는 빈 화면을 보게 되는것이다.

 

getStaticProps() 함수를 사용했기 때문에 !

getStaticProps()를 통해 빌드 시에 서버에서 데이터를 불러와 페이지를 생성하고, 생성된 페이지를 캐싱한다. 그래서 사용자가 페이지를 요청할 때 마다 서버에서 데이터를 가져오는 대신 캐싱된 페이지를 빠르게 반환한다.

따라서 초기 렌더링 속도를 높이고, 사용자가 빈화면을 보는 문제를 해결할 수 있다 !

'Next' 카테고리의 다른 글

[Next] 정적생성 / getStaticPath()  (0) 2023.02.20
[Next] 폴더 구조 및 동작  (0) 2023.02.20