next.js13 공식 문서 영문을 번역한 내용을 토대로 작성됩니다. 자세한 내용은 공식 사이트를 참고 하세요 |
로딩 UI와 스트리밍
특별한 파일인 loading.js를 사용하여 React Suspense와 함께 의미 있는 로딩 UI를 생성할 수 있습니다. 이 규칙을 사용하면 라우트 세그먼트의 내용이 로드될 때 즉시 로딩 상태를 서버에서 표시할 수 있습니다. 새로운 내용은 렌더링이 완료되면 자동으로 교체됩니다.
로딩 UI
즉시 로딩 상태
즉시 로딩 상태는 탐색 시 즉시 표시되는 대체 UI입니다. 스켈레톤 및 스피너와 같은 로딩 표시자나 커버 사진, 제목 등의 미래 화면의 작은 but 의미 있는 부분을 사전 렌더링할 수 있습니다. 이를 통해 사용자가 앱이 응답하는 것을 이해하고 더 나은 사용자 경험을 제공할 수 있습니다.
로딩 상태를 만들려면 로딩.js 파일을 폴더 내에 추가하면 됩니다.
app/dashboard/loading.tsx
export default function Loading() {
// 로딩 내에 로딩 스켈레톤과 같은 UI를 추가할 수 있습니다.
return <LoadingSkeleton />
}
동일한 폴더 내에서 loading.js는 layout.js 내에 중첩됩니다. 이로써 자동으로 page.js 파일과 하위 모든 항목을 <Suspense> 경계로 래핑합니다.
(개인정리) 루트 레이아웃.js 파일이 존재한다고 할때 같은 경로에 있는 page.js 와 loading.js 는 layout.js 내에 중첩된다. 또한, page.js와 loading.js 는 Suspense 컴포넌트에 감싸진 형태로 존재하는데, fallback 에 등록된 loading.js 파일이 우선 클라이언트에게 보여지고, page.js 의 준비가 끝나면 loading.js 는 page.js로 대체된다. |
알아두면 좋은 사항: |
서버 중심의 라우팅이라도 탐색은 즉시 발생합니다. 라우트의 내용이 완전히 로드되기 전에 다른 라우트로 탐색할 필요가 없으므로 탐색이 중단 가능합니다. 공유 레이아웃은 새로운 라우트 세그먼트가 로드되는 동안 상호작용 가능한 상태를 유지합니다. |
추천: Next.js는 이 기능을 최적화하기 위해 라우트 세그먼트(레이아웃 및 페이지)에 대해 loading.js 규칙을 사용하세요.
스트리밍과 Suspense
loading.js 외에도 사용자 고유의 UI 컴포넌트에 대해 수동으로 Suspense 경계를 생성할 수 있습니다. App Router는 Node.js 및 Edge 런타임 모두에 대해 스트리밍과 Suspense를 지원합니다.
스트리밍이란 무엇인가요?
React 및 Next.js에서 스트리밍 작동 방식을 이해하기 위해서는 서버 측 렌더링(Server-Side Rendering, SSR)과 그 제한 사항을 이해하는 것이 도움이 됩니다.
SSR에서 사용자가 페이지를 보고 상호작용할 수 있는 상태가 되려면 일련의 단계를 완료해야 합니다:
1. 먼저, 특정 페이지의 모든 데이터가 서버에서 가져와집니다.
2. 그런 다음 서버는 페이지의 HTML을 렌더링합니다.
3. 페이지의 HTML, CSS 및 JavaScript가 클라이언트로 전송됩니다.
4. 생성된 HTML 및 CSS를 사용하여 비대화식 사용자 인터페이스가 표시됩니다.
5. 마지막으로, React가 사용자 인터페이스를 하이드레이션하여 상호작용 가능하게 만듭니다.
이러한 단계는 순차적이고 블로킹적입니다. 즉, 서버는 모든 데이터를 가져온 후에만 페이지의 HTML을 렌더링할 수 있습니다. 그리고 클라이언트에서는 React가 페이지의 모든 컴포넌트 코드를 다운로드한 후에야 사용자 인터페이스를 하이드레이션할 수 있습니다.
React와 Next.js에서 SSR은 사용자가 가능한 빨리 비대화식 페이지를 볼 수 있도록 도와줍니다.
스트리밍을 통해 페이지의 HTML을 더 작은 청크로 나누고 이러한 청크를 서버에서 클라이언트로 점진적으로 전송할 수 있습니다.
(개인 정리) 일반적인 서버 사이드 렌더링에서는 서버 측에서 모든 컴포넌트가 준비된 이후에 클라이언트에게 한 번에 파일을 전송한다. 그렇기 때문에, 클라이언트 측에서는 서버에서 파일을 넘겨 받고, 다운로드 하여 렌더링 하기 까지 사용자는 빈 화면을 볼 수 밖에 없다. 그러나, 스트리밍 방식을 사용하면, 모든 데이터가 준비되어 있지 않아도 데이터를 청크 단위로 나눠 클라이언트로 보내주기 때문에 사용자는 일부 준비된 데이터를 즉시 다운로드하여 브라우저 화면 상에서 접할 수 있게 된다. |
스트리밍 작동 방식
이를 통해 페이지의 일부를 더 빨리 표시할 수 있으며 모든 데이터가 로드되기를 기다릴 필요가 없습니다.
스트리밍은 React의 컴포넌트 모델과 잘 어울립니다. 각 컴포넌트는 청크로 간주할 수 있습니다. 우선순위가 높은 컴포넌트(예: 제품 정보)나 데이터에 의존하지 않는 컴포넌트(예: 레이아웃)를 먼저 보낼 수 있으며 React는 조기에 하이드레이션을 시작할 수 있습니다. 우선순위가 낮은 컴포넌트(예: 리뷰, 관련 제품)는 데이터를 가져온 후에 같은 서버 요청에서 보낼 수 있습니다.
스트리밍은 페이지가 렌더링을 차단하지 않도록 긴 데이터 요청을 방지하려는 경우에 특히 유용합니다. 이로써 Time To First Byte (TTFB) 및 First Contentful Paint (FCP)를 줄일 수 있습니다. 또한 느린 장치에서 특히 Time to Interactive (TTI)를 개선하는 데 도움이 됩니다.
예시
<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 fallback={<p>Loading weather...</p>}>
<Weather />
</Suspense>
</section>
)
}
Suspense를 사용하면 다음과 같은 이점을 얻을 수 있습니다:
스트리밍 서버 렌더링 - 서버에서 클라이언트로 HTML을 점진적으로 렌더링합니다. 선택적 하이드레이션 - 사용자 상호작용을 기반으로 어떤 컴포넌트를 먼저 상호작용 가능하게 만들지 React가 우선순위를 정합니다. |
Suspense의 추가 예시 및 사용 사례에 대해서는 React 문서를 참조하세요.
SEO
Next.js는 generateMetadata 내부의 데이터 가져오기가 완료될 때까지 클라이언트로 UI를 스트리밍하기 전에 기다립니다. 이로써 스트리밍 응답의 첫 부분에 <head> 태그가 포함되도록 보장합니다.
스트리밍은 서버 렌더링이므로 SEO에 영향을 미치지 않습니다. Google의 웹 크롤러가 보는 페이지 모습 및 직렬화된 HTML(소스)을 확인하기 위해 Google의 모바일 친화성 테스트 도구를 사용할 수 있습니다.
상태 코드
스트리밍 시, 요청이 성공했음을 나타내기 위해 200 상태 코드가 반환됩니다.
서버는 여전히 리디렉션이나 notFound와 같은 상황에서 클라이언트에게 문제 또는 오류를 전달할 수 있습니다. 응답 헤더는 이미 클라이언트로 전송되었기 때문에 응답 상태 코드를 업데이트할 수 없습니다. 이것은 SEO에 영향을 미치지 않습니다.
'넥스트' 카테고리의 다른 글
[next.js] 8. 병렬 라우팅 (0) | 2023.08.30 |
---|---|
[next.js] 7. 에러 핸들링 (2) | 2023.08.28 |
[next.js] 5. 동적 라우팅 (0) | 2023.08.27 |
[next.js] 4. Route Groups (0) | 2023.08.26 |
[next.js] 3. Linking and Navigating :: next.js 에서의 라우트 간 이동법 ? (0) | 2023.08.26 |