Next.js App Router - Data Fetching(1)

Minkyu Shin·2023년 6월 7일
1

Next.js

목록 보기
6/9
post-thumbnail

Next.js

nextjs.org/docs 공식문서의 내용을 번역, 정리한 내용입니다.
사진 출처는 nextjs.org 공식문서입니다.

Data Fetching

Next.js App Router는 React와 웹 플랫폼 위에 세워진 새롭고 간단화 된 데이터 fetching 시스템을 제공한다.
앞으로 다룰 내용을 간단히 정리해 보면

  1. 서버 컴포넌트를 활용하여 서버에서 데이터를 fetch한다.
  2. waterfall을 최소화 하고, 로딩 시간을 줄이기 위해 데이터를 병렬적으로 fetch한다.
  3. 레이아웃과 페이지에서는 데이터가 실제 사용되는 곳에서 fetch한다. Next.js가 자동으로 트리 내의 요청 중 중복되는 것을 정리한다.
  4. Loding UI, Streaming과 Suspense를 사용하여 나머지 컨텐츠가 로딩되는 동안 점진적으로 페이지를 렌더하여 유저에게 보여준다.

The fetch() API

새로운 데이터 fetching 시스템은 fetch() Web API를 바탕으로 하여 서버 컴포넌트에서 asyncawait 을 사용 가능하도록 한다.

  • React는 fetch 를 확장하여 자동으로 중복 요청을 정리해 준다.
  • Next.js는 fetch 옵션 객체를 확장하여 각 요청에 각각의 캐싱과 갱신 규칙을 설정할 수 있도록 해준다.

Fetching Data on Server

Next.js는 가능하다면 데이터 fetching을 서버 컴포넌트에서 하는 것을 추천한다. 서버 컴포넌트는 항상 서버에서 데이터를 fetch하는데 이 방식의 장점은

  • 백엔드 데이터 자원에 직접 접근할 수 있다. (e.g. 데이터베이스)
  • 토큰이나 API 키와 같은 민감한 정보가 클라이언트에 노출되는 것을 방지하여 애플리케이션을 더 안전하게 유지할 수 있다.
  • 데이터 fetching과 렌더링이 동일한 환경에서 진행된다. 이는 클라이언트와 서버 사이의 지속적인 소통과 클라이언트의 메인 스레드의 작업을 줄인다.
  • 클라이언트에서 보내는 개개의 요청을 여러번 처리하는 것이 아닌 한번에 여러 데이터 fetch를 실행한다.
  • 클라이언트-서버 waterfall을 줄인다.
  • 지역에 따라 데이터 fetching이 데이터 소스와 더 가까운 곳에서 이뤄질 수 있어 느린 동작을 줄이고 성능을 개선할 수 있다.

Fetching Data at the Component Level

App Router에서는 레이아웃, 페이지 그리고 컴포넌트에서 데이터를 fetch할 수 있다. 데이터 fetching은 Streaming과 Suspense와도 호환 가능하다.

레이아웃과 부모 레이아웃 또는 children 컴포넌트 간에 데이터를 전달할 수 없다. 따라서 Next.js는 데이터를 필요로 하는 레이아웃에서 직접 데이터를 fetch 해올 것을 권장한다. 동일한 데이터를 여러번 요청하더라도 React와 Next.j가 요청을 캐싱하고 중복 정리(deduplicate)를 하여 한번을 초과하여 데이터가 fetch되는 것을 막아주기 때문이다.

Parallel and Sequential Data Fetching

컴포넌트 내에서 데이터를 fetch 할 때, 병렬 또는 순차적 데이터 fetching 패턴을 알아야 한다.

  • 병렬적인 데이터 fetching에서는 route의 요청들은 동일한 시점에 로딩 된다. 이는 클라이언트-서버 간 waterfall을 줄이고 데이터를 로딩하는 총 시간을 줄여준다.
  • 순차적인 데이터 fetching에서는 route의 요청들은 서로 의존적이게 waterfall을 만든다. 예를 들어 하나의 fetch가 다른 fetch의 결과에 따라 달라지거나, 다음 fetch 전에 특정 조건이 만족되었으면 좋겠다고 생각할 경우를 들 수 있다. 다만, 이런 동작 방식은 의도되지 않을 수 있고 더 긴 로딩 시간으로 귀결될 수 있다.

Automatic fetch() Request Deduping

만약 트리 내의 여러 컴포넌트에서 동일한 데이터를 fetch해야 한다면, Next.js는 자동으로 동일한 입력을 가진 fetch 요청(GET)을 임시 캐시에 캐싱해 준다. 이 최적화는 렌더링 과정에서 동일한 데이터가 한번을 초과하여 fetch되는 것을 막아준다.

  • 서버에서 캐시는 렌더링 과정이 완료될 때까지 서버 요청 생명주기 동안 유지된다.
    - 이러한 최적화는 레이아웃, 페이지, 서버 컴포넌트, generateMetadata , generateStaticParams 에서 만들어진 fetch 요청에 적용된다.
    - 정적 생성에서도 적용된다.
  • 클라이언트에서는 전체 페이지 reload 전 session이 지속될 때 유지된다.

단, POST 요청은 자동으로 정리되지 않는다.
만약 fetch 를 사용할 수 없다면 React는 수동으로 요청 동안 데이터를 캐싱할 수 있도록 cache 함수를 제공한다.

Static and Dynamic Data Fetching

데이터에는 두가지 종류가 있다:

  • 정적인 데이터는 블로그 포스트와 같이 자주 변경되지 않는 데이터이다.
  • 동적인 데이터는 장바구니와 같이 자주 바뀌거나 유저에게 특정된 데이터를 말한다.

Next.js는 기본적으로 정적 fetch를 한다. 빌드 타임에 데이터가 fetch 되고, 캐싱되며 각 요청 시마다 캐싱된 데이터를 재사용한다. 개발자는 정적인 데이터가 어떻게 캐싱되고 갱신될지 통제할 수 있다.

정적인 데이터를 사용함으로써 얻는 장점은 2가지가 있다:

  1. 요청의 수를 줄여 데이터베이스의 부하를 줄일 수 있다.
  2. 로딩 성능을 개선하기 위해 데이터가 자동으로 캐싱된다.

하지만, 데이터가 특정 유저에게 개인화되어 있거나, 최신의 데이터를 항상 fetch하고 싶다면 요청을 dynamic 이라고 정하고 캐싱 없이 매 요청마다 데이터를 fetch할 수 있다.

Caching Data

캐싱은 데이터를 특정 장소(e.g. CDN)에 저장하여 요청 때마다 원 소스에서 re-fetch 될 필요가 없더록 하는 과정이다.

Next.js 캐시는 전역적으로 분배 가능한 HTTP 캐시이다. 이는 캐시가 자동으로 규모화 되어 사용하는 플랫폼(e.g. Vercel)에 따라 여러 부분에 걸쳐 공유될 수 있다는 것을 의미한다.

Next.js는 fetch() 함수의 options 객체를 확장하여 서버에서의 각 요청이 자신의 캐싱 동작 방식을 정할 수 있도록 해준다. component-level 데이터 fetching과 함께 데이터가 사용되는 애플리케이션 코드에서 캐싱을 설정할 수 있도록 해준다.

서버 렌더링이 진행될 때, 즉 Next.js가 fetch를 하는 시점에 데이터가 이미 활용 가능한지 알아보기 위해 캐시를 확인한다. 만약 활용이 가능하다면 캐시된 데이터를 반환하고, 아니라면 데이터 fetch를 해 와서 이후 요청을 위해 데이터를 저장해 둔다.

Revalidating Data

갱신은 캐시를 삭제하고 최신 데이터를 re-fetch하는 과정이다. 이는 데이터에 변경이 생겼을 때 전체 애플리케이션을 다시 빌드하지 않고도 최신 버전의 데이터를 보여주는 것을 보장해 줄 수 있다.

Next.js는 두가지 종류의 갱신을 지원한다:

  1. Background : 특정 시간 간격으로 데이터를 갱신한다.
  2. On-demand : 업데이트가 있을 때마다 데이터를 갱신한다.

Streaming and Suspense

Streaming과 Suspense는 점진적으로 렌더링을 진행하고 렌더링이 완료된 UI를 클라이언트에 stream 해주는 새로운React 기능이다.
(Streaming에 대한 구체적 설명은 여기 Loading UI and Streaming 파트에...)

서버 컴포넌트와 중첩된 레이아웃을 활용하면 페이지의 데이터를 필요로 하지 않는 부분을 즉각적으로 렌더링 하고 데이터를 fetch하는 부분을 로딩 상태를 보여줄 수 있다. 즉, 유저가 페이지와 상호작용하기 전에 전체 페이지가 로딩되는 것을 기다릴 필요가 없어지는 것이다.

Old Methods

getServerSideProps , getStaticProps , getInitialProps 와 같은 Next.js 데이터 fetching 메소드는 App Router에서 지원되지 않는다. 단, Page Router에서는 동일하게 사용 가능하다.

profile
개발자를 지망하는 경영학도

1개의 댓글

comment-user-thumbnail
2024년 1월 7일

getServerSideProps , getStaticProps , getInitialProps 와 같은 Next.js 데이터 fetching 메소드는 App Router에서 지원되지 않는다. 단, Page Router에서는 동일하게 사용 가능하다.

=> 이거 알고 싶어서 엄청 많이 찾아다녔는데 정리 잘 해주셔서 감사합니다. 공식문서 기반이라 확실해서 좋네요

답글 달기