[Next 13] Routing - Loading UI와 Streaming

Jeongho·2023년 9월 4일
0
  • loading.js 특수 파일은 React Suspense를 사용하여 의미 있는 로딩 UI를 만드는 데 도움이 됩니다. 이 규칙을 사용하면 경로 세그먼트의 콘텐츠가 로드되는 동안 서버에서 즉시 로드 상태(스피너 또는 스켈레톤 ui)를 표시할 수 있습니다. 렌더링이 완료되면 새 콘텐츠가 자동으로 교체됩니다.

즉시 로딩 상태 (Instant Loading States)

  • 즉시 로딩 상태는 탐색 시 즉시 표시되는 대체 UI입니다. (스피너 또는 스켈레톤 ui)
  • 사용자는 앱이 응답하고 있음을 이해하고 더 나은 사용자 경험을 제공할 수 있습니다.
  • 폴더 안에 loading.js 파일을 추가하여 로드 상태를 만듭니다.
// app/dashboard/loading.tsx
export default function Loading() {
  // You can add any UI inside Loading, including a Skeleton.
  return <LoadingSkeleton />
}
  • 같은 폴더안에 있는 page.js와 children들을 Suspense로 자동적으로 래핑합니다.
  • 알아두면 좋은 점
    • 서버 중심 라우팅을 사용하더라도 탐색은 즉각적입니다.
    • 탐색은 중단 가능합니다. 즉, 경로를 변경할 때 다른 경로로 이동하기 전에 경로의 콘텐츠가 완전히 로드될 때까지 기다릴 필요가 없습니다.
    • 새 경로 세그먼트가 로드되는 동안 공유 레이아웃은 대화형으로 유지됩니다.

Suspense를 이용한 Streaming

  • loading.js 외에도 자체 UI 컴포넌트에 대한 Suspense Boundaries를 수동으로 생성할 수도 있습니다.
  • 앱 라우터는 Node.js 및 Edge 런타임 모두에 대해 Suspense를 사용한 스트리밍을 지원합니다.

Streaming이란?

  • React 및 Next.js에서 스트리밍이 작동하는 방식을 배우려면 SSR과 그 제한 사항을 이해하는 것이 도움이 됩니다.
  • SSR을 사용하면 사용자가 페이지를 보고 상호 작용하기 전에 완료해야 하는 일련의 단계가 있습니다.
    1. 먼저, 특정 페이지의 모든 데이터를 서버에서 가져옵니다.
    2. 그런 다음 서버는 페이지의 HTML을 렌더링합니다.
    3. 페이지의 HTML, CSS 및 JavaScript가 클라이언트로 전송됩니다.
    4. 비대화형 사용자 인터페이스는 생성된 HTML 및 CSS를 사용하여 표시됩니다.
    5. 마지막으로 React는 사용자 인터페이스를 대화형으로 만들기 위해 하이드레이션을 진행합니다.
  • 이러한 단계는 순차적이며 차단됩니다. 즉, 모든 데이터를 가져온 후에만 서버가 페이지의 HTML을 렌더링할 수 있습니다.
  • 그리고 클라이언트에서 React는 페이지의 모든 컴포넌트에 대한 코드가 다운로드된 후에만 UI를 하이드레이션할 수 있습니다.
  • React 및 Next.js를 사용한 SSR은 사용자에게 비대화형 페이지를 가능한 한 빨리 표시하여 인지된 로딩 성능을 향상시키는 데 도움이 됩니다.
  • 그러나 페이지가 사용자에게 표시되기 전에 서버에서 모든 데이터 가져오기가 완료되어야 하므로 여전히 속도가 느릴 수 있습니다.
  • 스트리밍을 사용하면 페이지의 HTML을 더 작은 청크로 나누고 점진적으로 해당 청크를 서버에서 클라이언트로 보낼 수 있습니다. (먼저 온 데이터는 먼저 보낸다)
  • 이를 통해 UI가 렌더링되기 전에 모든 데이터가 로드될 때까지 기다리지 않고 페이지의 일부를 더 빨리 표시할 수 있습니다.
  • 스트리밍은 각 컴포넌트가 하나의 덩어리로 간주될 수 있기 때문에 React의 컴포넌트 모델과 잘 작동합니다.
  • 우선 순위가 더 높거나(예: 제품 정보) 데이터에 의존하지 않는 구성 요소(예: 레이아웃)가 먼저 전송될 수 있으며 React는 더 일찍 수화를 시작할 수 있습니다.
  • 우선 순위가 낮은 구성 요소(예: 리뷰, 관련 제품)는 해당 데이터를 가져온 후 동일한 서버 요청으로 보낼 수 있습니다.
  • 스트리밍은 TTFB(Time To First Byte)를 줄일 수 있으므로 긴 데이터 요청으로 인해 페이지 렌더링이 차단되는 것을 방지하려는 경우 특히 유용합니다.
  • 첫 번째 콘텐츠가 포함된 페인트(FCP).과 TTI(Time to Interactive)를 개선하는 데 도움이 됩니다.

Example

  • <Suspense>로 비동기 작업(데이터 가져오기)을 수행하는 컴포넌트를 래핑하고 해당 작업이 진행되는 동안 대체 UI를 표시한 다음 작업이 완료되면 컴포넌트를 교체하는 방식으로 작동
import { Suspense } from 'react'
import { PostFeed, Weather } from './Components'
 
export default function Posts() {
  return (
    <section>
      <Suspense fallback={<p>Loading feed...</p>}>
        <PostFeed />
      </Suspense>
      <Suspense fallback={<p>Loading weather...</p>}>
        <Weather />
      </Suspense>
    </section>
  )
}
  • Suspense를 사용하면 다음과 같은 이점을 얻을 수 있습니다.
    • 스트리밍 서버 렌더링 - 서버에서 클라이언트로 HTML을 점진적으로 렌더링합니다.
    • 선택적 수화 - React는 사용자 상호 작용을 기반으로 어떤 컴포넌트를 먼저 대화식으로 만들 것인지 우선 순위를 정합니다.

SEO

  • Next.js는 UI를 클라이언트로 스트리밍하기 전에 generateMetadata 내부에서 데이터를 가져오기가 완료될 때까지 기다립니다. 이렇게 하면 스트리밍된 응답의 첫 번째 부분에 <head> 태그가 포함됩니다.
  • 스트리밍은 서버에서 렌더링되므로 SEO에 영향을 주지 않습니다.

상태 코드

  • 스트리밍할 때 요청이 성공했음을 알리기 위해 200 상태 코드가 반환됩니다.
  • 예를 들어 redirect 또는 notFound를 사용할 때 서버는 스트리밍된 콘텐츠 자체 내에서 클라이언트에 오류나 문제를 계속 전달할 수 있습니다.
  • 응답 헤더가 이미 클라이언트에 전송되었으므로 응답의 상태 코드를 업데이트할 수 없습니다. 이는 SEO에 영향을 미치지 않습니다.

Reference

profile
주도적으로 문제를 정의하고 코드를 통해 해결합니다.

0개의 댓글