Next.js dynamic 사용 시 주의사항

Jindolph·2024년 8월 7일

Next.js 동적 로딩(dynamic)에서 발생하는 차이점

Next.js의 dynamic 함수를 사용하여 동적 컴포넌트를 로드할 때 발생하는 문제와 그 원인을 분석해보겠습니다. 이 글에서는 두 가지 방식의 차이점과 이를 사용하는 방법에 대해 설명합니다.

오랜시간 삽질해서 결국 원인을 찾았습니다.
에러로그 등이 없기 때문에 원인 분석이 어려운 관계로 여러분의 시간절약을 위해 포스팅합니다.
혹시라도 제 해석이 틀리거나 분석된 다른 명확한 원인을 보신분은 댓글로 공유 부탁드립니다.

dynamic 코드분석

두 인자를 받으며, 첫번째는 dynamicOptions, 두번째는 options 입니다.

아래 코드와 같이 첫번째 인자를 객체 지정 시, loader 필드에 로더를 할당할 수 있습니다.
두번째는 () => 함수 호출로 로더컴포넌트 직접 할당할 수 있습니다.

두 방식의 동작 매커니즘이 달라서 객체로 할당렌더링 문제가 발생합니다.

export default function dynamic<P = {}>
  (
      dynamicOptions: DynamicOptions<P> | Loader<P>, 
      options?: DynamicOptions<P>
  ): React.ComponentType<P>;

export type DynamicOptions<P = {}> = LoadableGeneratedOptions & {
    loading?: (loadingProps: DynamicOptionsLoadingProps) => JSX.Element | null;
    loader?: Loader<P> | LoaderMap;
    loadableGenerated?: LoadableGeneratedOptions;
    ssr?: boolean;
    /**
     * @deprecated `suspense` prop is not required anymore
     */
    suspense?: boolean;
};

export declare type Loader<P = {}> = (() => LoaderComponent<P>) | LoaderComponent<P>;

두 가지 방식 비교

  1. 옵션 객체를 사용하는 방식

    const DynamicMapPage = dynamic({
      loader: () => import('./components/Map'),
      ssr: false
    });
  2. 단순한 함수 호출 방식

    const DynamicMapPage = dynamic(() => import('./components/Map'), { ssr: false });

발생하는 문제

  1. 옵션 객체 방식에서 클라이언트 웹브라우저 화면이 검은 바탕으로 표시되고, 에러는 발생하지 않음. (렌더링만 안되는 현상)
  2. 단순 함수 호출 방식은 정상적으로 동작함.

차이점 분석

두 방식 간의 차이점은 dynamic 함수의 첫 번째 인자를 해석하는 방식에서 발생합니다.

  1. 옵션 객체 방식 (DynamicOptions):

    • 이 방식은 Next.js 내부에서 loaderssr 옵션을 포함한 객체를 해석하여 컴포넌트를 로드합니다.
    • 이 때 loader가 비동기 함수로 실행되고, ssr 옵션이 적용되는 과정에서 문제가 발생할 수 있습니다.
  2. 단순 함수 방식 (Loader):

    • 이 방식은 Next.js가 동적 로딩을 처리하는 기본적인 방법입니다.
    • 이 방식은 더 단순하며, 비동기 함수가 직접 실행되어 로드 과정이 보다 명확합니다.

왜 첫 번째 방식이 문제를 일으키는가?

  1. loader 함수와 ssr 옵션의 처리 순서:

    • 첫 번째 방식에서는 loader 함수와 ssr 옵션이 함께 객체로 전달되기 때문에, Next.js가 이를 해석하여 처리하는 과정에서 비동기 로드와 SSR 비활성화 설정이 충돌할 가능성이 있습니다.
    • 특히 ssr 옵션이 비동기 로드 함수와 동시에 처리되는 방식이 Next.js 내부에서 제대로 처리되지 않을 수 있습니다.
  2. Next.js 내부 처리 로직의 차이:

    • Next.js는 dynamic 함수의 두 가지 형태를 다르게 처리합니다. 단순 함수 형태는 보다 직접적이고 단순한 반면, 객체 형태는 더 복잡한 내부 처리가 필요합니다.
    • 공식 문서나 다른 자료에서도 두 가지 방식이 동일하게 작동하지 않을 수 있다고 언급되어 있습니다. 이는 Next.js의 동적 로딩 처리 로직의 복잡성 때문입니다.

공식 문서 및 자료 참고

Next.js 공식 문서에서도 두 가지 방식의 사용을 설명하지만, 단순 함수 방식이 더 일반적이고 권장되는 방식입니다. 공식 문서에서도 일부 옵션과의 조합이 제대로 작동하지 않을 수 있음을 언급합니다.

해결 방안 및 권장 사항

  • 단순 함수 방식 사용: 비동기 로딩과 SSR 비활성화를 동시에 처리하려면 단순 함수 방식을 사용하는 것이 더 안전하고 확실합니다.
  • 문제 발생 시 디버깅: 옵션 객체 방식이 필요할 경우, 로딩 중 발생하는 모든 로그와 네트워크 요청을 확인하여 어떤 단계에서 문제가 발생하는지 확인합니다.

따라서, 문제가 발생하지 않는 단순 함수 방식으로 사용하는 것이 권장됩니다. 이는 Next.js 내부의 비동기 로드 처리 로직과 관련된 문제를 피할 수 있기 때문입니다.

profile
Hello World!

0개의 댓글