본문 바로가기

공부/Next

Next.js 알아보기 5 (Suspense, Loading, Error, Streaming SSR)

반응형

 

Loading UI 📖

Next.js 14의 App router에서 비동기 컴포넌트가 로드되는 동안 사용자에게 로딩 상태를 표시하는 기능입니다.

 

왜 중요할까?

`사용자 경험 개선`: 로딩 중인 상태를 명확히 표시해 사용자의 불안감을 줄이고, 시스템이 응답하고 있음을 알립니다.

`사용자의 불필요한 행동 문제 해결`: 현재 상태를 제공해 불필요한 클릭이나 페이지 이탈을 방지할 수 있습니다.

`향상된 SEO 및 접근성`: 로딩 UI는 페이지의 일부분이 빠르게 렌더링 되어 SEO 성능을 향상하고, 사용자가 페이지를 더 빠르게 접근할 수 있도록 합니다.

 

사용방법

로딩 컴포넌트 작성

// app > loading.tsx

export default function Loading() {
  return <div>Loading...</div>;
}

 

비동기 컴포넌트 로드

`suspense`컴포넌트는 비동기 작업을 처리할 때 대체 UI를 제공하는 역할을 합니다. 로딩 중일 때 `Loading`컴포넌트를 표시합니다.

import { Suspense } from 'react';

export default function Page() {
  return (
    <div>
      <Suspense fallback={<Loading />}>
        <ProductList />
      </Suspense>
    </div>
  );
}

 

Suspense와 Streaming SSR 📖

next.js 14에서는 React의 서스펜스와 스트리밍 기능을 사용해 서버 사이드 렌더링을 더욱 효율적으로 처리할 수 있습니다. 데이터를 부분적으로 스트리밍해 사용자가 페이지를 더 빨리 볼 수 있게 합니다.

 

서버에서 준비된 콘텐츠를 조각조각 클라이언트에 보내는 방식입니다. 

 

사용방법

import { Suspense } from 'react';
import Loading from './loading';

export default function Page() {
  return (
    <div>
      <Suspense fallback={<Loading />}>
        <ComponentA />
      </Suspense>
      <Suspense fallback={<Loading />}>
        <ComponentB />
      </Suspense>
      <Suspense fallback={<Loading />}>
        <ComponentC />
      </Suspense>
    </div>
  );
}

 

스트리밍과 서스펜스를 사용하면 여러 비동기 컴포넌트들을 최적화된 속도로 나눠서 불러올 수 있고, 사용자가 더 나은 경험을 할 수 있도록 웹 애플리케이션을 최적화할 수 있게 만들어줍니다.

 

Error 📖

특정 라우트 세그먼트에 맞춘 `error.ts`를 생성하고 오류가 발생한 부분만 격리해 애플리케이션의 나머지 부분이 계속 작동할 수 있도록 유지할 수 있습니다.

 

코드

✅Error component 는 꼭 클라이언트 컴포넌트여야 한다는 점!!

// ~/error.tsx
'use client';

import { useEffect } from 'react';

export default function Error({
  error,
  reset,
}: {
  error: Error & { digest?: string }
  reset: () => void
}) {
  useEffect(() => {
    console.error(error);
  }, [error]);

  return (
    <div>
      <h2>Something went wrong!</h2>
      <button onClick={() => reset()}>Try again</button>
    </div>
  );
}

 

왜 Error 컴포넌트는 클라이언트 컴포넌트여야 하나요

 

React Error Boundary와 관련이 있는데요, React의 오류 경계는 클라이언트 측에서만 동작합니다 React 컴포넌트 트리 내에서 발생하는 오류를 잡아내고, 폴백 UI를 렌더링 하는 역할을 합니다. 그래서 서버 사이드에서는 작동하지 않기 때문에 클라이언트 컴포넌트로 정의되어야 합니다. 

 

Layout Error 핸들링

`error`파일은 동일한 라우트 세그먼트의 `layout.tsx`또는`template.tsx`컴포넌트에서 발생하는 오류를 처리해주지 않습니다.

이런 오류를 처리하려면 레이아웃의 부모 세그먼트에 `error.tsx`파일을 추가해야 합니다.

 

그럼 루트 레이아웃, 템플릿 내에서 발생하는 오류는 어떻게 처리할까요

 

`global-error.tsx` 파일을 사용해 처리할 수 있습니다.

'use client';

export default function GlobalError({
  error,
  reset,
}: {
  error: Error & { digest?: string }
  reset: () => void
}) {
  return (
    <html>
      <body>
        <h2>Something went wrong!</h2>
        <button onClick={() => reset()}>Try again</button>
      </body>
    </html>
  );

 

Error 복구하기

오류 컴포넌트는 사용자가 오류를 복구하도록 시도할 수 있는 `reset()`함수를 제공해 줍니다.

'use client';

export default function Error({
  error,
  reset,
}: {
  error: Error & { digest?: string }
  reset: () => void
}) {
  return (
    <div>
      <h2>Something went wrong!</h2>
      <button onClick={() => reset()}>Try again</button>
    </div>
  );
}

 

그래서 Error 컴포넌트 안에서 사용자에게 다시 불러오는 버튼을 제공할 수 있습니다.

 

Error UI와 Loading UI를 잘 사용한다면 사용자들에게 빠르고 안전하고 선언적인 UI를 제공할 수 있습니다.

 

다음 게시물

 

Next.js 알아보기 6 (Asset 최적화)

이미지 최적화 📖next.js는 자동으로 이미지 크기를 최적화해주는 이미지 컴포넌트 `Image` 컴포넌트를 제공해 줍니다. `크기 최적화`: 각 기기에 맞는 크기의 이미지를 자동으로 제공하고, Webp 및

mingos-habitat.tistory.com

 

반응형