프로그래밍 언어/NEXT.JS

[NEXT.JS] Dynamic Import

doomole 2024. 9. 4. 10:35
728x90

개요

이전 개발자가 개발한 프로젝트를 보고 무지성으로 프로젝트 구조를 잡아서 개발을 수행했었는데, 프로젝트를 완성해서 정상적으로 서비스를 하고 있지만 정확히 어떤 이유로 사용하는 지 모를 코드들이 있기 때문에 NEXT.JS를 더욱 이해하기 위해 하나씩 파헤쳐보려고 합니다.

 

 

구조 설명

현재 모든 app router 내부 디렉토리는 아래와 같은 구조입니다.

_module 디렉토리에는 각 컨테이너에서 사용하는 component들과 css를 모아놓았습니다.

app
    - home
    	- _module
    	- page.tsx
        - page.body.tsx
    - contents
       	- _module
    	- page.tsx
        - page.body.tsx
    - notice
       	- _module
    	- page.tsx
        - page.body.tsx

 

아래는 page.tsx와 page.body.tsx 내부 코드입니다.

// page.tsx
import dynamic from 'next/dynamic'
import Loading from '@/components/loading'

const HomeBody = dynamic(() => import('./page.body'), {
  loading: () => <Loading />,
})

export default function Home() {
  return <HomeBody />
}

// page.body.tsx
'use client'

import HomeBanner from './_module/home.banner'
import HomeTag from './_module/home.tag'
import HomeCard from './_module/home.card'
import { useHomeContentsQuery } from '@/queries/query.home'
import useErrorStore from '@/stores/store.error'
import { useEffect } from 'react'
import useFooterStore from '@/stores/store.footer'

// Container - 홈
export default function HomeBody() {
  const { data, isSuccess } = useHomeContentsQuery()
  const { setError } = useErrorStore()
  const { setReady } = useFooterStore()

  useEffect(() => {
    if (isSuccess) {
      if (data.status !== 200) {
        setError(true, data.message)
      } else {
        setReady(true)
      }
    }
  }, [data])

  return (
    <>
      {data?.data && (
        <>
          <HomeBanner bannerList={data.data.resMainBannerList} />
          <HomeCard
            accList={data.data.resWorldstockPortfolioGroupListAcc}
            threeList={data.data.resWorldstockPortfolioGroupListThree}
          />
          <HomeTag content={data.data.resWorldstockHotStock} />
        </>
      )}
    </>
  )
}

 

이 때, page.tsx에서 dynamic import를 통해 page.body.tsx를 가져오는데 이렇게 사용하는 이유에 대해 알아보고자 합니다.

 

 

Dynamic Import

Dynamic Import는 JavaScript의 import() 함수로 모듈을 비동기적으로 로드하는 기능입니다. 일반적으로 모듈을 import 키워드로 동기적으로 불러오지만, import()를 사용하면 모듈을 필요할 때 비동기적으로 로드할 수 있습니다.

 

이 방식은 코드 스플리팅의 기본이 되며, 애플리케이션의 크기를 줄이고 성능을 최적화하는 데 중요한 역할을 합니다.

더보기

코드 스플리팅

애플리케이션을 작은 청크(파일)로 분할하여, 필요한 부분만 로드하게 합니다. 이는 앱의 초기 로딩 시간을 크게 줄일 수 있으며, 사용자가 필요로 하지 않는 코드는 처음에 로드되지 않기 때문에 더 빠른 사용자 경험을 제공합니다.

 

장점

지연 로딩 (Lazy Loading)

지연 로딩은 코드나 리소스가 필요한 시점에서만 로드되도록 하여, 불필요한 자원의 낭비를 줄입니다. 이를 통해 초기 페이지 로딩 성능을 크게 개선할 수 있습니다.

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

 

이 코드는 SomeComponent를 지연 로딩하고, 서버 사이드 렌더링(SSR)을 비활성화한 예입니다. 즉, 클라이언트 측에서만 컴포넌트를 렌더링합니다.

 

로딩 컴포넌트 표시

동적 로딩 중 로딩 상태를 나타내는 UI를 제공할 수 있습니다. 이는 동적으로 로드되는 컴포넌트가 클라이언트에 의해 로드되는 동안 사용자에게 로딩 화면을 표시하는 기능을 제공합니다.

const HomeBody = dynamic(() => import('./page.body'), {
  loading: () => <Loading />,
});

위 코드에서는 HomeBody가 로드되는 동안 Loading 컴포넌트를 보여줍니다.

 

 

사용 사례

const HeavyComponent = dynamic(() => import('./HeavyComponent'));

function SomeComponent() {
  const [show, setShow] = useState(false);

  return (
    <>
      <button onClick={() => setShow(true)}>Show Component</button>
      {show && <HeavyComponent />}
    </>
  );
}

 

위 컴포넌트는 Dynamic Import의 아래 기능들을 활용한 사례입니다.

 

 

페이지/컴포넌트 기반 코드 스플리팅

페이지나 컴포넌트 단위로 코드 스플리팅을 통해, 사용자가 필요하지 않은 페이지의 코드를 로드하지 않도록 최적화할 수 있습니다. 이 방식은 앱의 확장성 및 성능 개선에 큰 도움이 됩니다.

사용자 인터랙션 기반 컴포넌트 로딩

특정 사용자 동작(예: 버튼 클릭)에 따라 특정 컴포넌트를 동적으로 로드하는 방식으로도 활용됩니다. 이를 통해, 불필요한 컴포넌트를 초기 로드에서 제외하고, 사용자 상호작용이 발생한 후에만 컴포넌트를 로드할 수 있습니다.

비용이 큰 라이브러리 지연 로딩

사용자가 페이지에 진입할 때 처음부터 모든 라이브러리를 로드하는 것은 비효율적일 수 있습니다. 특히, 무거운 라이브러리나 특정 조건에서만 필요한 경우, 이를 지연 로딩하여 성능을 최적화할 수 있습니다.

 

 

주의 사항

 

SEO에 미치는 영향

SSR을 비활성화하면, 해당 컴포넌트는 클라이언트에서만 렌더링되기 때문에, 이 컴포넌트가 검색 엔진 최적화(SEO)에 중요한 부분이라면 주의해야 합니다. 서버에서 렌더링되지 않으면 검색 엔진이 콘텐츠를 제대로 인덱싱하지 못할 수 있습니다.

네트워크 지연

동적 로딩은 네트워크 지연에 의존하기 때문에, 사용자가 동적 컴포넌트를 사용하는 데 시간이 걸릴 수 있습니다. 이런 상황에서 적절한 로딩 화면을 제공해야 합니다.

 

 

문의사항이나 피드백은 댓글로 남겨주세요.

 

 

 

 

'프로그래밍 언어 > NEXT.JS' 카테고리의 다른 글

[NEXT.JS] Enums(열거형)과 Constants(상수)  (0) 2024.09.04
[NEXT.JS] 없는 페이지 처리(Not Found Page)  (0) 2024.09.04
[NEXT.JS] Zustand  (0) 2024.07.31
[NEXT.JS] SWR  (0) 2024.07.31
[NEXT.JS] Axios  (0) 2024.07.31