이전 Layout, Server Components에 이어 Next13에 추가된 여러 가지 Feature들을 계속 적어보고자 한다.
Streaming?
기존 SSR의 flow를 생각해보면 아래와 같다.
1. Server(API)로 부터 Data를 가져옴
2. Server(Next.js)에서 HTML을 렌더링 함
3. Client(browser)에서 코드(HTML)를 받음
4. JavaScript를 받아와 Hydrating함
이 과정이 모두 끝나기 전까지 유저는 페이지와 상호작용을 할 수 없다.
그렇다면 이 문제를 어떻게 해결해야 할까..?
여기서 바로 제안되는 방법이 Streaming이다.
이미지처럼 HTML을 작게 나누어 모든 데이터가 로드되기 전 준비된 컴포넌트는 미리 완성해 상호작용할 수 있게 해주는 기술을 Streaming이라고 한다.
이 기술을 사용해 우선순위가 높은 컴포넌트를 먼저 작동하게 해 줄 수 있다.
말만으로 이해하기는 어려우니 사진을 함께 첨부해 보면,
위와 같이 컴포넌트 단위대로 따로 로드하고 렌더링 하게 되어 맨 위 컴포넌트의 TTI는 매우 단축된 것을 알 수 있다.
How to use Streaming in Next13?
Next13에서 이 기술을 사용할 수 있는 방법은 두 가지가 존재한다.
loading.js
먼저 loading.js(loading.tsx)를 활용하는 방법을 소개해보면
이와 같이 app아래 loading.js(loading.tsx)를 만들게 되면
layout.js, page.js를 포함한 아래 jsx파일들은 전부 Suspense로 래핑 되게 되어 loading 될 때까지 loading.js이 반환하는 Element를 렌더링 하게 된다.
<Suspense>
이 방법은 익숙한 사람도 있을 것 같다.
아래와 같이 비동기 컴포넌트를 Suspense로 감싸고 Suspense 내부에 fallback에 로딩바나 스피너와 같은 로딩 컴포넌트를 넣는 방식이다.
function Page() {
return (
<div>
<Suspense fallback={<Loading />}>
{/* @ts-expect-error Async Server Component */}
<FetchingComponent />
</Suspense>
</div>
)
}
여기 보면 FechingComponent (비동기 컴포넌트) 위에 @ts-expect-error Async Server Component이라는 주석을 추가한 모습을 볼 수 있다.
현재 이 주석을 포함하지 않으면 아래와 같은 에러가 발생한다
JSX 구성 요소를 사용할 수 없습니다 해당 변환 형식 'Promise<Element>'은(는) 유효한 JSX 요소가 아닙니다.
이 이슈는 TypeScript 이슈로 현재 Upstream에서 수정 중이니 곧 이 주석 없이도 작업할 수 있을 것 같다.
적용 영상
Streaming을 적용하면 아래와 같이 비동기 컴포넌트가 로딩 중이어도 다른 컴포넌트와 상호작용을 할 수 있다.
이렇게 Next.js에서 제안하는 Streaming에 대해서 글을 써보았습니다.
SSR을 사용하면서 각각 비동기 컴포넌트들을 따로 제어할 수 있는 Streaming은 아주 매력적인 것 같아 자주 사용할 것 같다.
아마 이렇게 글로만 보기보다 코드를 직접 보면 이해가 빠를 것 같아 아래에 예시 코드도 첨부해 놓았습니다.
예시 코드: https://github.com/bysxx/next-ts-template-tailwind/tree/master/app/example
'front-end > next.js' 카테고리의 다른 글
Server Components 활용하는 방법 (0) | 2023.10.12 |
---|---|
Next.js 13.5 (2) | 2023.10.11 |
Next 13.4 - App Router 안정화 버전 출시 with Turbopack, Server Actions (0) | 2023.05.13 |
Next13 + TypeScript Template 공유 (Next13 쉽게 시작하는법) (0) | 2023.04.12 |
Next13을 알아보자 - 1 (Nested Layout, Server Components) (0) | 2023.04.09 |