logo
PostsInvestingHomebarArticlesAbout

Next.js 13 / 07. Loading UI and Streaming

2023.06.15 / 6min

Intro

loading.js는 React Suspense를 이용해서 Loading UI를 만든다. 이 규칙을 사용하면 서버에서 경로 세그먼트의 콘텐츠가 로드되는 동안 즉시 로딩 상태를 보여줄 수 있으며, rendering이 완료되면 자동으로 변경된다.


TOC

Instant Loading States

instant loading state라는 것은 navigation시 fallback UI다. skeletons, spinners와 같은 로딩 표시기를 pre-render하여 표지 사진, 제목 등과 같이 작지만 향후 화면에 보여줄 부분을 나타낼 수 있다. 이를 통해 사용자가 앱이 반응하고 있음을 이해하고 더 나은 사용자 경험을 제공할 수 있다.

폴더 안에 loading.js 파일을 추가하여 로딩 상태를 만들 수 있다.

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

같은 폴더에서 loading.jslayout.js안에 중첩된다. page.js 파일과 그 아래의 모든 하위 파일은 자동으로 <Suspense> boundary로 감싸진다.


Streaming with Suspense

loading.js외에도 자체 UI 컴포넌트에 대한 Suspense Boundaries를 수동으로 생성할 수도 있다. App Router는 Node.js 및 Edge runtime 모두에 대해 Suspense를 사용한 스트리밍을 지원한다.

What is Streaming?

React와 Next.js에서 스트리밍이 어떻게 작동하는지 알아보려면 서버 측 렌더링(SSR)과 그 한계를 이해하는게 좋다.

SSR을 사용하면 사용자가 페이지를 보고 상호작용하기 전에 완료해야하는 단계가 있다:

  1. 먼저 특정 페이지의 모든 데이터를 서버에서 가져옴.
  2. 서버에서 페이지의 HTML을 렌더링.
  3. 페이지의 HTML, CSS 및 JavaScript가 클라이언트로 전송.
  4. 생성된 HTML과 CSS를 사용해 비대화형 사용자 인터페이스(non-interactive user interface) 표시.
  5. 마지막으로 React Hydrate로 사용자 인터페이스에 대화형 인터페이스(interactive user interface)로 만듬.

server-rendering-without-streaming-chart

이러한 단계는 순차적이고 차단적이여서 서버는 모든 데이터를 가져온 후에만 페이지의 HTML을 렌더링할 수 있다. 그리고 클라이언트에서는 페이지의 모든 컴포넌트에 대한 코드가 다운로드된 후에만 React가 UI에 Hydrate할 수 있다.

React 및 Next.js를 사용한 SSR은 사용자에게 non-interactive 페이지를 최대한 빨리 보여줌으로써 체감 로딩 성능을 개선하는 데 도움이 됩니다.

그러나 페이지가 사용자에게 표시되기 전에 서버에서 모든 데이터 가져오기를 완료해야하므로 여전히 속도가 느리다.

Streaming을 사용하면 페이지의 HTML을 더 작은 청크로 분할하여 서버에서 클라이언트로 점진적으로 전송할 수 있다.
이렇게 하면 UI를 렌더링하기 전에 모든 데이터가 로드될 때까지 기다릴 필요 없이 페이지의 일부를 더 빨리 표시할 수 있다.

Streaming은 각 컴포넌트를 청크로 간주할 수 있기 때문에 React's component model과 함께 잘 작동한다. 우선 순위가 높거나(예: 제품 정보) 데이터에 의존하지 않는 컴포넌트(예: layout)를 먼저 전송할 수 있으며, React는 hydration을 더 일찍 시작할 수 있다. 우선 순위가 낮은 컴포넌트(예: 리뷰, 관련 제품)는 데이터를 가져온 이후에 서버 요청으로 전송할 수 있다.

Streaming은 긴 데이터 요청으로 인해 페이지 렌더링이 차단되는 것을 방지할 때 특히 유용하다. Streaming은 TTFB(Time To First Byte)와 FCP(First Contentful Paint)를 줄일 수 있기 때문이다. 또한 특히 느린 디바이스에서 Time to Interactive(TTI)를 개선하는 데 도움이 됩니다.

  • 서스펜스를 사용하면 다음과 같은 이점을 가져갈 수 있다.
    1. Streaming Server Rendering - 서버에서 클라이언트로 HTML을 점진적으로 렌더링한다.
    2. Selective Hydration - React는 사용자 상호작용에 따라 어떤 컴포넌트를 먼저 인터랙티브하게 만들지 우선 순위를 정한다.

SEO

  • Next.js는 generateMetadata 내부의 데이터 가져오기가 완료될 때까지 기다렸다가 client로 UI를 streaming한다. 이렇게 하면 streaming된 응답의 첫 부분에 <head> 태그가 포함되도록 보장한다.
  • streaming은 서버에서 렌더링되므로 SEO에 영향을 미치지 않는다. Google의 모바일 친화적 테스트 도구를 사용하여 Google의 웹 크롤러에 페이지가 어떻게 표시되는지 확인하고 직렬화된 HTML(소스)을 볼 수 있다.

Reference


avatar
snyungSoftware Engineer(from. 2018)
social-mailsocial-githubsocial-facebooksocial-book