Next.js

Next js 데이터 패칭 방식

_HelloWorld_ 2024. 12. 17. 14:18

기본 방식

기본적으로 서버 사이드 방식과 클라이언트 사이드 방식을 모두 지원하는 하이브리드 프레임워크입니다. 즉, 어떤 방식으로 페이지를 렌더링할지는 개발자가 설정에 따라 선택할 수 있습니다. 기본적으로 Next.js는 SSG(Static Site Generation)와 SSR(Server-Side Rendering) 방식을 모두 제공하며, 클라이언트 사이드의 동적 기능도 지원

요약

기본적으로 서버 사이드 방식: Next.js는 서버 사이드에서의 페이지 렌더링을 기본적으로 제공하며, SSGSSR을 지원

클라이언트 사이드 지원: Next.js는 또한 클라이언트 사이드 기능도 지원하며, 동적 임포트, 클라이언트 사이드 라우팅, API Routes 등 다양한 클라이언트 사이드 기술을 제공


데이터 패칭 방식

1. SSG (Static Site Generation)

  • 개요: 빌드 시점에 데이터를 가져와 HTML 파일을 생성합니다. 페이지 요청 시 서버는 정적 HTML 파일을 제공하므로 빠른 속도를 자랑합니다.
  • 사용 방법: getStaticProps를 사용하여 데이터를 미리 가져옵니다.
  • 장점: 빠른 페이지 로딩 속도, SEO 최적화.
  • 단점: 페이지가 빌드 시에만 생성되므로, 데이터가 실시간으로 갱신되지 않습니다.
export async function getStaticProps() {
  const data = await fetchDataFromAPI();
  return {
    props: { data }
  };
}

2. SSR (Server-Side Rendering)

  • 개요: 요청이 있을 때마다 서버에서 데이터를 가져와 페이지를 동적으로 렌더링합니다. 매 요청 시마다 새로운 HTML을 생성합니다.
  • 사용 방법: getServerSideProps를 사용하여 요청 시마다 데이터를 가져옵니다.
  • 장점: 항상 최신 데이터를 제공합니다.
  • 단점: 서버에서 매번 페이지를 렌더링하므로 성능에 부담을 줄 수 있습니다.
export async function getServerSideProps() {
  const data = await fetchDataFromAPI();
  return {
    props: { data }
  };
}

3. ISR (Incremental Static Regeneration)

  • 개요: SSG와 유사하지만, 페이지를 일정 주기마다 재생성할 수 있습니다. 이를 통해 정적 페이지의 성능과 동적 페이지의 유연성을 동시에 갖출 수 있습니다.
  • 사용 방법: getStaticProps와 revalidate 속성을 사용하여 페이지를 주기적으로 재생성합니다.
  • 장점: 초기에는 정적 페이지로 제공되며, 이후 변경된 페이지만 재생성하므로 성능이 뛰어납니다.
  • 단점: 초기 빌드 후, 일정 시간 동안 페이지가 갱신되지 않을 수 있습니다.
export async function getStaticProps() {
  const data = await fetchDataFromAPI();
  return {
    props: { data },
    revalidate: 60, // 60초마다 페이지를 재생성
  };
}

요약

  • SSG: 빌드 시에 페이지를 미리 생성.
  • SSR: 요청마다 서버에서 페이지를 동적으로 생성.
  • ISR: 정적 페이지를 주기적으로 재생성하여 성능과 최신 데이터의 장점 결합.
  • 동적 임포트: 코드 분할을 통해 필요할 때만 추가적인 코드 로드.
방식 설명 실행 위치 언제 실행되는지
SSG (Static Site Generation) 빌드 시에 데이터를 가져와 정적 페이지를 생성. 서버 사이드 빌드 시에 한 번만 실행되어 정적 HTML을 생성
SSR (Server-Side Rendering) 요청 시마다 데이터를 가져와 동적 페이지를 생성. 서버 사이드 페이지 요청 시마다 서버에서 실행되어 동적 페이지를 생성
ISR (Incremental Static Regeneration) 정적 페이지를 주기적으로 재생성하여 성능과 최신 데이터를 결합. 서버 사이드 페이지가 요청될 때마다 또는 설정된 주기에 따라 서버에서 페이지를 재생성

데이터를 가져오는 주요 함수

페이지를 렌더링하기 위해 데이터를 가져오는 데 사용되는 주요 함수들인 getStaticProps, getServerSideProps, getStaticPaths, revalidate

1. getStaticProps (Static Site Generation)

  • 설명: 이 함수는 페이지를 정적으로 생성할 때 데이터를 가져오는 데 사용됩니다. Next.js는 빌드 시 이 함수를 실행하여 데이터를 미리 가져오고, 이를 바탕으로 정적 HTML 파일을 생성합니다. 이후 해당 페이지는 서버 없이 빠르게 제공됩니다.
  • 주요 사용 사례: 콘텐츠가 자주 변하지 않는 페이지 (예: 블로그 게시물, 문서 등)
    • getStaticProps는 async 함수여야 하며, 반드시 props를 반환해야 합니다.
    • 데이터를 가져오는 데 시간이 오래 걸리는 경우 API 호출이나 DB 쿼리 등을 수행할 수 있습니다.
export async function getStaticProps() {
  const data = await fetchDataFromAPI();
  return {
    props: { data }, // 페이지에 전달할 데이터
  };
}

 

  • 장점:
    • 빠른 페이지 로딩 (정적 파일을 제공하므로).
    • SEO 최적화가 용이.
  • 단점:
    • 데이터가 빌드 시에만 고정되므로, 실시간 데이터 변경이 필요하면 적합하지 않음.

2. getServerSideProps (Server-side Rendering)

  • 설명: 이 함수는 서버에서 동적으로 페이지를 렌더링할 때 사용됩니다. 페이지 요청이 있을 때마다 Next.js는 이 함수가 실행되어 데이터를 가져온 후 서버에서 HTML을 생성하여 클라이언트에 전송합니다.
  • 주요 사용 사례: 실시간 데이터가 필요한 페이지 (예: 사용자 맞춤형 대시보드, 검색 결과 등)
  • 사용법:
    • getServerSideProps도 async 함수로 정의되며, props를 반환해야 합니다.
    • 매 요청 시마다 데이터를 갱신하므로 항상 최신 데이터를 제공합니다.
export async function getServerSideProps() {
  const data = await fetchDataFromAPI();
  return {
    props: { data }, // 페이지에 전달할 데이터
  };
}

 

 

  • 장점:
    • 항상 최신 데이터를 제공할 수 있음.
  • 단점:
    • 서버에서 매번 페이지를 렌더링해야 하므로 성능이 떨어질 수 있음.
    • 페이지 로딩 시간이 느려질 수 있음.

3. getStaticPaths (SSG with Dynamic Routes)

  • 설명: 이 함수는 동적 라우트와 함께 사용되어야 합니다. 페이지가 동적으로 생성되는 경우 (예: [id].js와 같은 동적 라우트), Next.js는 어떤 페이지를 생성해야 할지 알지 못합니다. getStaticPaths는 어떤 경로들을 빌드할지 알려주기 위한 함수입니다.
  • 주요 사용 사례: 동적 경로를 사용하는 페이지 (예: 블로그 포스트, 상품 페이지 등)
  • 사용법:
    • getStaticPaths는 동적 경로의 목록을 반환합니다.
    • getStaticProps와 함께 사용되며, getStaticPaths에서 제공하는 경로에 대해 getStaticProps가 실행됩니다.
export async function getStaticPaths() {
  const paths = await fetchPathsFromAPI();
  return {
    paths, // 동적 경로 목록
    fallback: 'blocking', // 페이지가 빌드되지 않은 경우 대처 방식
  };
}

export async function getStaticProps({ params }) {
  const data = await fetchDataForPage(params.id);
  return {
    props: { data },
  };
}

 

 

  • fallback 옵션:
    • false: 빌드되지 않은 경로에 대한 요청은 404를 반환합니다.
    • true: 빌드되지 않은 경로를 요청하면 빈 페이지를 보여주고, 페이지가 생성된 후 다시 렌더링합니다.
    • blocking: 빌드되지 않은 경로를 요청하면, 페이지가 준비될 때까지 기다린 후 반환합니다.
  • 장점:
    • 동적 경로에 대한 SSG를 사용할 수 있어 성능이 우수합니다.
  • 단점:
    • 동적 경로가 많은 경우, 빌드 시간이 길어질 수 있습니다.
방식 설명 실행 위치 언제 실행되는지
getStaticProps 빌드 시에 데이터를 가져와 정적 페이지를 생성. 서버 사이드 빌드 시에 실행되어 데이터를 가져오고 정적 HTML을 생성
getServerSideProps 요청 시마다 데이터를 가져와 동적 페이지를 생성. 서버 사이드 페이지 요청 시마다 실행되어 동적 HTML을 생성
getStaticPaths 동적 경로를 사용하는 페이지에서 어떤 경로들을 생성할지 정의. 서버 사이드 빌드 시에 실행되어 동적 경로 목록을 반환
revalidate (ISR) 정적 페이지를 일정 주기마다 재생성하여 최신 데이터를 반영 (ISR). 서버 사이드 설정된 주기마다 정적 페이지를 재생성하여 최신 데이터 반영

 


데이터 패칭 방식

1. 클라이언트 사이드 데이터 패칭

  • 설명: 클라이언트 사이드에서는 데이터 요청이 브라우저에서 직접 이루어집니다. 즉, 페이지가 로드된 후 JavaScript를 사용하여 API를 호출하거나 데이터를 가져옵니다. 이 방식은 보통 사용자 인터랙션 이후 데이터를 동적으로 불러오는 데 사용됩니다.
  • 주요 특징:
    • 브라우저에서 실행: 클라이언트 측에서 JavaScript가 실행되며 API를 호출하거나 데이터를 가져옵니다.
    • 동적 업데이트: 페이지가 처음 로드될 때는 기본적인 HTML과 JavaScript 파일만 로드되고, 이후에 필요한 데이터는 비동기적으로 가져옵니다.
    • SEO: 클라이언트 사이드에서 데이터를 가져오기 때문에, 검색 엔진이 페이지의 초기 HTML을 크롤링할 때는 데이터가 없을 수 있습니다. 따라서 SEO에 불리할 수 있습니다.
  • 장점:
    • 페이지 로딩 속도가 빠를 수 있음 (첫 번째 요청은 빠르고, 이후 데이터만 비동기적으로 가져옴).
    • 서버 리소스를 덜 사용하고, 클라이언트에서만 데이터를 처리.
  • 단점:
    • SEO 최적화가 어려울 수 있음.
    • 처음 페이지를 로드할 때 빈 화면 또는 로딩 상태를 표시해야 할 수 있음.
  • 예시: 클라이언트에서 데이터를 비동기적으로 가져오는 예시 (React의 useEffect와 fetch 사용)
import { useEffect, useState } from 'react';

const MyComponent = () => {
  const [data, setData] = useState(null);

  useEffect(() => {
    fetch('/api/data')
      .then(response => response.json())
      .then(data => setData(data));
  }, []);

  if (!data) {
    return <div>Loading...</div>;
  }

  return <div>{data}</div>;
};

2. 서버 사이드 데이터 패칭

  • 설명: 서버 사이드에서는 서버에서 데이터를 가져옵니다. Next.js와 같은 서버 사이드 렌더링(SSR) 프레임워크는 요청이 있을 때마다 서버에서 데이터를 처리하고 HTML을 동적으로 렌더링합니다. 데이터는 클라이언트로 보내기 전에 서버에서 미리 준비되어 페이지에 포함됩니다.
  • 주요 특징:
    • 서버에서 실행: 서버가 페이지를 렌더링할 때 데이터를 가져오고, 페이지를 완성하여 클라이언트에 보냅니다.
    • SEO 최적화: 서버에서 데이터를 처리하여 HTML을 반환하므로 검색 엔진이 페이지를 크롤링할 때 이미 렌더링된 페이지를 볼 수 있습니다. SEO에 유리합니다.
    • 초기 로딩: 페이지가 서버에서 완전히 렌더링되어 전달되므로, 클라이언트가 페이지를 처음 로드할 때 데이터가 이미 준비되어 있습니다.
  • 장점:
    • SEO 최적화: 초기 HTML에 데이터가 포함되어 있어 검색 엔진에 최적화됩니다.
    • 초기 렌더링 시 데이터가 모두 준비되어 있기 때문에 사용자가 기다릴 필요가 없습니다.
  • 단점:
    • 서버에 부하가 발생할 수 있음 (매번 요청 시마다 데이터를 처리하고 페이지를 렌더링).
    • 서버 리소스를 많이 사용하므로 성능에 영향을 줄 수 있음.
  • 예시: getServerSideProps를 사용한 서버 사이드 데이터 패칭 예시
export async function getServerSideProps() {
  const data = await fetchDataFromAPI();
  return {
    props: { data }
  };
}

const MyPage = ({ data }) => {
  return <div>{data}</div>;
};

클라이언트 사이드 vs 서버 사이드 데이터 패칭 차이

특징 클라이언트 사이드 데이터 패칭 서버사이드 데이터 패칭
데이터 요청 위치 브라우저 (클라이언트 측) 서버 측 (서버에서 데이터를 가져오고 렌더링 후 클라이언트로 전달)
초기 렌더링 시 데이터 첫 로딩 시 빈 화면 또는 로딩 상태 표시 페이지가 서버에서 미리 렌더링되어 클라이언트에 완전한 HTML 전달
SEO SEO에 불리할 수 있음 (데이터가 자바스크립트 실행 후 로드되므로) SEO에 유리함 (서버에서 렌더링된 HTML을 제공하므로 검색 엔진에 최적화)
성능 페이지 로딩 후 데이터를 비동기적으로 가져와 처리 (빠른 로딩) 서버에서 매 요청마다 데이터를 처리하므로 서버 부하 발생 가능
사용 사례 실시간 데이터 업데이트가 필요한 UI, 사용자 상호작용 후 데이터 로드 페이지 초기 로딩 시 데이터가 필요하거나 SEO 최적화가 중요한 페이지

CSR / UseEffect를 사용하는 방식

클라이언트 측 렌더링 방식으로, 웹 페이지의 콘텐츠가 브라우저에서 직접 렌더링되는 방법입니다. 즉, 초기 HTML 페이지는 최소한의 구조만 포함하고, 그 이후 필요한 JavaScript 파일을 로드하여 데이터를 가져오고 페이지를 동적으로 렌더링하는 방식

 

CSR (Client-Side Rendering) 특징

1. 초기 로딩

  • CSR에서는 최초 요청 시 서버에서 빈 HTML과 JavaScript만 제공하고, 실제 콘텐츠는 JavaScript가 실행되고 데이터를 가져온 후 렌더링됩니다.
  • 서버에서 HTML을 미리 렌더링하지 않음으로써 초기 렌더링이 느려질 수 있습니다. 즉, 브라우저가 JavaScript를 다운로드하고 실행할 때까지는 페이지의 실제 콘텐츠가 표시되지 않습니다.

2. 데이터 가져오기

  • CSR 방식에서는 페이지가 로드된 후, JavaScript가 클라이언트에서 데이터를 비동기적으로 가져옵니다. 일반적으로 fetch나 axios와 같은 API를 통해 서버에서 데이터를 가져옵니다.
  • 이때 사용되는 데이터는 주로 AJAXREST API, GraphQL 등을 통해 클라이언트 측에서 요청됩니다.

3. 페이지 동적 렌더링

  • 클라이언트에서 데이터를 받아와 동적으로 HTML을 생성하여 렌더링합니다. 이는 React, Vue.js, Angular 등과 같은 SPA (Single Page Application) 프레임워크에서 사용됩니다.
  • 페이지 전환 시 서버로부터 새로운 페이지를 로드하지 않고, 클라이언트 내에서 JavaScript가 DOM을 수정하여 페이지를 업데이트합니다.

4. 라우팅

  • CSR에서는 클라이언트 측 라우팅을 사용합니다. 즉, 페이지가 바뀔 때 서버로 새로운 요청을 보내지 않고 JavaScript가 URL을 처리하여 필요한 콘텐츠를 클라이언트 측에서 가져옵니다.
  • React에서는 react-router-dom과 같은 라이브러리를 통해 클라이언트 측 라우팅을 구현합니다.

CSR 장점

  1. 빠른 페이지 전환:
    • 첫 페이지 로딩 후 클라이언트에서 페이지를 동적으로 렌더링하므로, 이후의 페이지 전환은 서버 요청 없이 매우 빠르게 일어납니다. 이는 주로 SPA 애플리케이션에서 큰 장점입니다.
  2. 서버 부하 감소:
    • 모든 페이지 렌더링을 클라이언트에서 처리하므로, 서버는 초기 HTML과 JavaScript만 제공하고 페이지 렌더링은 클라이언트에서 수행되기 때문에 서버 부하가 줄어듭니다.
  3. 동적인 사용자 경험:
    • 클라이언트에서 JavaScript가 데이터를 가져오고 DOM을 업데이트하므로, 사용자에게 동적이고 반응성이 뛰어난 경험을 제공합니다. 예를 들어, 애니메이션, 실시간 업데이트 등 클라이언트 사이드에서 효율적으로 처리할 수 있습니다.
  4. SEO와 서버 사이드 로딩 없이 빠른 사용자 경험 제공:
    • 앱의 첫 페이지가 로드된 이후, 사용자가 페이지를 이동하거나 데이터를 가져오는 데 있어 서버 요청 없이 빠른 반응을 보장합니다. 이 점은 사용자 경험(UX)을 향상시킵니다.

CSR 단점

  1. 초기 로딩 시간 지연:
    • CSR 방식에서는 처음 페이지가 로드될 때 JavaScript 파일을 다운로드하고 실행해야 하므로, 첫 번째 페이지 로딩 속도가 상대적으로 느릴 수 있습니다. 특히 대용량의 JavaScript 파일을 다운로드해야 할 경우, 로딩 시간이 길어질 수 있습니다.
    • 또한, 초기 페이지 로딩 시 SEO가 중요한 페이지에서는 문제가 될 수 있습니다.
  2. SEO (검색 엔진 최적화):
    • CSR 방식은 초기 HTML이 빈 페이지와 같은 상태로 로드되기 때문에, 검색 엔진 봇이 페이지 내용을 인식하는 데 어려움이 있을 수 있습니다. 이는 SEO에 불리한 점이 됩니다.
    • 서버 사이드 렌더링(SSR) 방식이나 정적 사이트 생성(SSG) 방식은 초기 HTML에 콘텐츠가 포함되므로 검색 엔진 최적화에 유리합니다.
  3. JavaScript 의존성:
    • CSR은 JavaScript 실행에 의존하므로, 만약 사용자가 JavaScript를 비활성화하거나 지원하지 않는 환경이라면 페이지가 제대로 작동하지 않거나 빈 화면이 표시될 수 있습니다.
  4. 브라우저 성능 문제:
    • 클라이언트에서 모든 렌더링을 처리하기 때문에, 성능이 낮은 디바이스에서는 느려지거나 반응 속도가 떨어질 수 있습니다. 특히 복잡한 애플리케이션에서는 클라이언트에서의 렌더링 부담이 커질 수 있습니다.

CSR 사용 시 적합한 경우

  • 동적인 사용자 경험이 필요한 경우 (예: 실시간 데이터 업데이트, 사용자 상호작용에 따른 변화).
  • SEO가 크게 중요하지 않은 애플리케이션.
  • 상호작용이 많고 복잡한 UI를 처리해야 하는 애플리케이션.
  • 사용자가 페이지 전환 후 빠른 반응을 기대하는 경우 (예: 대시보드 애플리케이션, 채팅 애플리케이션 등).

결론

언제 SSR, CSR, SSG를 사용할지 요약

랜더링 방식 사용 시점 예시 페이지
SSR (서버 사이드) 실시간 데이터 필요 + SEO가 중요한 페이지 블로그, 뉴스 페이지, 마케팅 페이지
CSR (클라이언트 사이드) SEO가 필요 없고 사용자 상호작용이 많은 페이지 대시보드, 채팅, 개인화된 페이지
SSG (정적 사이트) 자주 바뀌지 않는 콘텐츠를 미리 렌더링 (SEO 최적화) 블로그 글, 문서 페이지
ISR (재생성) 최신 데이터를 주기적으로 반영하면서 정적 페이지 유지 상품 목록, 자주 업데이트되는 게시글

페이지마다 적절히 분리해서 사용하는 것이 중요합니다. 이렇게 하면 성능 최적화사용자 경험(UX), SEO를 모두 만족

 

페이지마다 SSR과 CSR을 분리해야 하는 이유

  1. SEO가 중요한 페이지SSR (Server-Side Rendering)
    • 서버에서 HTML을 미리 렌더링해서 브라우저에 제공하므로, 검색 엔진이 콘텐츠를 쉽게 크롤링할 수 있습니다.
    • 예: 블로그, 뉴스 페이지, 상품 상세 페이지와 같이 SEO가 중요한 페이지.
  2. SEO가 중요하지 않은 페이지CSR (Client-Side Rendering)
    • 데이터를 클라이언트에서 동적으로 가져오고 렌더링하는 방식입니다. 초기 로딩은 느릴 수 있지만 이후 빠른 페이지 전환이 가능합니다.
    • 예: 사용자 개인화 대시보드, 관리 화면, 실시간 업데이트가 많은 페이지 등.
  3. 성능 최적화SSG + ISR (Static Site Generation + Incremental Static Regeneration)
    • 데이터를 빌드 시점에 정적으로 생성하거나, revalidate를 활용해 주기적으로 최신 데이터로 재생성할 수 있습니다.
    • 예: 블로그 목록 페이지, 자주 변경되지 않는 콘텐츠 페이지.