데이터 로딩과 같은 비동기 작업이 완료될 때까지 컴포넌트 트리의 일부 렌더링을 중단하거나 대기시키는 기능을 제공합니다.
import React, { Suspense } from 'react';
const MyComponent = React.lazy(() => import('./MyComponent'));
function App() {
return (
<Suspense fallback={<div>Loading...</div>}>
<MyComponent />
</Suspense>
);
}
예를 들어 다음과 같은 상황에서 React.lazy 를 통해 MyComponent가 사용자의 실제 요구 시점에 로드될 수 있도록 사용했을 때, Suspense는 사용자의 요청이 들어오고 MyComponent가 전부 로드되기 전까지 MyComponent 컴포넌트의 렌더를 막고, 대체 컴포넌트를 반환하게 된다.
lazy load는 컴포넌트, 페이지, 라이브러리 등을 코드 스플릿팅을 통해 청크 단위로 쪼개고 해당 청크를 필요에 따라 독립적으로 렌더링하는 기술이다.
그렇게 되면 메인 번들에 레이지 로드에 포함된 컴포넌트 , 페이지, 라이브러리 등이 포함되지 않아 초기 로딩 성능이 향상된다.
기본적으로 React에서 제공하는 ErrorBoundary와 Suspense의 계층 구조는 다음과 같이 되어있다.
<ErrorBoundary>
<Suspense fallback={<loading />}>
<Page />
</Suspense>
</ErrorBoundary>
위의 경우처럼 ErrorBoundary와 suspense를 같이 사용할 때의 계층구조가 이렇게 된다.
여기서 Suspense의 경우 Page가 로딩이 되기 전에 잠깐 멈추고, loading 으로 대체 페이지를 제공하게 된다.
그리고 Page가 전부 로딩이 됐을 때, Page 페이지를 보여주게 되는 것이다.
여기서 Page가 전부 로딩이 됐다는 것의 기준이 뭘까?
NextJs 서버 컴포넌트에서 데이터 가져올 때, 데이터 패칭이 이루어지는 동안까진 대체 페이지를 제공하게 된다.
const LazyComponent = React.lazy(() => import('./LazyComponent'));
예를 들어 LazyComponent 라는 컴포넌트가 중요도가 떨어지거나 당장 화면에 포함되지 않는 요소라면, 초기 로드 시에 포함하지 않고 나중에 로드할 수 있게 처리하는 것이다.
use 라는 훅을 사용해서 값을 가져오는 경우
React 18버전에서 제공하는 use훅은 Context와 promise를 받을 수 있는데, 이 때 promise의 resolve 될때까지 Suspense가 기다렸다가 Page를 보여주게 된다.
Nextjs에서 제공하는 loading.tsx, error.tsx도 마찬가지로 React 의 Suspense 를 사용하게 된다.
다만, NextJS에선 계층구조를 사용하지 않아도 같은 레벨에 loading, error 페이지만 둬도 계층구조를 적용시켜주는 것이다.
출처: https://nextjs.org/docs/app/building-your-application/routing/loading-ui-and-streaming
Suspense, ErrorBoundary 정말 잘 사용하고 있는데
잘 정리 하셨네요! 잘 읽고 갑니다!