[ Routing ] Loading UI and Streaming

차차·2023년 5월 17일
0

Next Docs

목록 보기
8/34
post-thumbnail
post-custom-banner

loading.js를 사용하면 React Suspense와 함께 의미 있는 로딩 UI를 생성할 수 있다. 이 기능을 사용하면 라우트 세그먼트의 내용을 로드하는 동안 서버로부터 즉시 로딩 상태를 표시하고, 렌더링이 완료되면 자동으로 새로운 콘텐츠로 교체된다.



Instant Loading States

즉시 로딩 상태는 네비게이션 시 즉시 표시되는 대체 UI이다. 스켈레톤 및 스피너와 같은 로딩 인디케이터나 향후 화면의 작지만 의미 있는 부분(커버 사진, 제목 등)을 사전 렌더링할 수 있다. 이를 통해 사용자가 앱이 응답 중임을 이해하고 더 나은 사용자 경험을 제공할 수 있다.


로딩 상태는 폴더 안에 loading.js 파일을 추가하여 생성한다.

// app/dashboard/loading.tsx

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

동일한 폴더 안에 loading.jslayout.js 안에 중첩된다. 이는 자동으로 page.js 파일과 그 아래의 모든 자식 요소를 <Suspense> 경계로 감쌀 것이다.


알아두면 좋은 점

  • 서버 중심 라우팅(server-centric routing)을 사용하더라도 네비게이션은 즉시 진행된다.
  • 네비게이션은 중단 가능하며, 다른 경로로 이동하기 전에 라우트의 콘텐츠가 완전히 로드될 필요가 없다.
  • 새로운 라우트 세그먼트가 로드되는 동안 공유 레이아웃은 상호 작용 가능하다.
  • Next.js는 이 기능을 최적화하기 때문에 라우트 세그먼트(레이아웃 및 페이지)에 loading.js 규칙을 사용하는 것을 권장한다.


Streaming with Suspense

스트리밍 기능을 사용하기 위해 loading.js 외에도 직접 UI 구성 요소에 대한 Suspense Boundary를 만들 수 있다. 앱 라우터는 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는 이를 조기에 하이드레이션할 수 있다. 데이터를 가져온 후에는 우선순위가 낮은 컴포넌트(예: 리뷰, 관련 제품)도 동일한 서버 요청에서 전송할 수 있다.

스트리밍은 페이지의 렌더링이 차단되지 않도록 긴 데이터 요청을 방지하고, Time To First Byte (TTFB)와 First Contentful Paint (FCP)를 줄일 수 있어 매우 유익하다. 특히 느린 기기에서는 Time to Interactive (TTI)를 개선하는 데 도움이 된다.


예시

<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 사용 이점

  • Streaming Server Rendering : 서버에서 클라이언트로 HTML을 점진적으로 렌더링한다.

  • Selective Hydration : 사용자 상호작용에 따라 React가 어떤 컴포넌트를 먼저 인터랙티브하게 만들어야 할지 우선순위를 정한다.


SEO

Next.js는 UI를 클라이언트로 스트리밍하기 전에 generateMetadata 내부의 데이터 페칭이 완료될 때까지 기다린다. 이를 통해 스트리밍 응답의 첫 부분에 <head> 태그가 포함됨을 보장한다.

스트리밍은 서버에서 렌더링되므로 SEO에 영향을 주지 않는다. Google의 웹 크롤러가 웹페이지를 어떻게 보는지 확인하고 직렬화된 HTML(소스)을 확인하기 위해 Google의 Mobile Friendly Test 도구를 사용할 수 있다.



[출처]
https://nextjs.org/docs/app/building-your-application/routing/loading-ui-and-streaming

profile
나는야 프린이
post-custom-banner

0개의 댓글