본문 바로가기

Next.js

Next.js 11-6 Routing Loading UI and Streaming

  특수 파일 loading.js는 React Suspense로 의미 로딩 UI를 만드는 데 도움이 된다. 이 규칙을 사용하면 경로 세그먼트의 콘텐츠가 로드되는 동안 서버에서 즉시 로드 상태를 표시할 수 있으며 렌더링이 완료되면 새 콘텐츠가 자동으로 교체된다.

 

  • 인스턴스 로딩 상태

  즉시 로드 상태는 탐색 시 즉시 표시되는 대체 UI이다. 스켈리톤 및 스피너와 같은 로딩 표시기 또는 표지 사진, 제목 등과 같은 미래 화면의 작지만 의미 있는 부분을 사전 렌더링할 수 있다. 이를 통해 사용자는 앱이 응답하고 있음을 이해하고 더 나은 사용자 경험을 제공할 수 있다.

  폴더 안에 loading.js 파일을 추가하여 로드 상태를 만든다.

// app/dashboard/loading.tsx

export default function Loading() {
  // You can add any UI inside Loading, including a Skeleton.
  return <LoadingSkeleton />;
}

 

  같은 폴더에서 loading.js는 layout.js 안에 중첩된다. <Suspense> 경계에서 page.js 파일과 그 아래의 모든 자식을 자동으로 래핑 한다.

  알아둘 만한 점은 서버 중심 라우팅을 사용하는 경우에도 탐색이 즉각적이다. 그리고 내비게이션은 중단 가능하다. 즉, 경로 변경 시 다른 경로로 이동하기 전에 경로 콘텐츠가 완전히 로드될 때까지 기다릴 필요가 없다. 공유 레이아웃은 새 경로 세그먼트가 로드되는 동안 대화식으로 유지된다.

  Next.js가 이 기능을 최적화하기 때문에 경로 세그먼트(레이아웃 및 페이지)에 loading.js 규칙을 사용하는 것이 좋다.

 

  • 서스펜스 스트리밍

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

  React 및 Next.js에서 Streaming이 작동하는 방식을 알아보려면 SSR(Server-Side Rendering) 및 제한 사항을 이해하는 것이 좋다. 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)를 개선하는 데 도움이 된다.

 

  • Examples

  <Suspense>는 비동기 작업(예: 데이터 가져오기)을 수행하는 컴포넌트를 래핑하고 작업이 진행되는 동안 대체 UI(예: 스켈레톤, 스피너)를 표시한 다음 작업이 완료되면 컴포넌트를 교체하는 방식으로 작동한다.

// app/dashboard/page.tsx

import { Suspense } from 'react';
import { PostFeed, Weather } from './Components';

export default function Posts() {
  return (
    <section>
      <Suspense fallback={<p>Loading feed...</p>}>
        <PostFeed />
      </Suspense>
      <Suspense>
        <Weather />
      </Suspense>
    </section>
  )
}

  Suspense를 사용하면 다음과 같은 이점을 얻을 수 있다.

  1. 스트리밍 서버 렌더링 - 서버에서 클라이언트로 HTML을 점진적으로 렌더링 한다.
  2. 선택적 수화 - React는 사용자 상호 작용을 기반으로 먼저 상호 작용할 컴포넌트의 우선순위를 지정한다.

 

  • SEO

  Next.js는 UI를 클라이언트로 스트리밍 하기 전에 generateMetadata 내에서 데이터 가져오기가 완료될 때까지 기다린다. 이렇게 하면 스트리밍 응답의 첫 번째 부분에 <head> 태그가 포함된다.

  스트리밍은 서버에서 렌더링 되므로 SEO에 영향을 미치지 않는다. Google의 모바일 친화성 테스트 도구를 사용하여 페이지가 Google 웹 크롤러에 어떻게 표시되는지 확인하고 직렬화된 HTML(출처)을 볼 수 있다.

 

출처: Next.js 공식문서

'Next.js' 카테고리의 다른 글

Next.js 11-8 Routing Parallel Routes  (0) 2023.05.26
Next.js 11-7 Routing Error Handling  (0) 2023.05.25
Next.js 11-5 Routing Dynamic Routes  (0) 2023.05.24
Next.js 11-4 Routing Route Groups  (0) 2023.05.24
Next.js 11-3 Routing Linking and Navigating  (0) 2023.05.23