Dynamic Import

2024. 7. 7. 17:32코딩/UNCLASSIFIED

728x90

Dynamic Import 동적 임포트

전에 프로젝트 진행 중 빌드 크기 및 초기 렌더링 속도 이슈가 있어서 도입했던 것인데

지금도 물론 초보지만 그때는 걸음마 뗀 망아지였기에 그냥 쓰라길래 쓰는 그런 기술인데 궁금해서 찾아봤다.

내가 당시 사용한 것과 각 블로그나 문서에서 설명하는 예시가 비슷해 이해가 더 빠르게 됐다. 각설하고 알아보자


Dynamic?

'동적'이라는 말이 붙은 것 처럼 경우에 따라 필요 코드를 import 하는 것으로

버튼을 눌렀을 때 보여져야하는 모달창이라던가, nav바 클릭에 따라 보여지는 콘텐츠가 다른경우 사용한다.

이로써 초기에 불필요한 파일  초기 번들에 포함되는 것을 막고 별도의 번들에 포함시켜 초기에 로딩해야 하는 스크립트의 사이즈를 줄일 수 있게 된다.

당연히 초기에 로딩되는 번들 사이즈가 작으면 앱이 더 빨리 로드된다. 사용자가 빈 화면에서 기다리는 시간이 줄어든다.

이로인해 앱을 더 빨리 보고 인터렉션 하도록 개선해 사용자 경험 또한 향상시킬 수 있다.

 

로딩 전략

dynamic import를 통해 보여지는 컴포넌트가 전환되는 동안엔 Next를 사용 시엔, SuspenseLoading을 사용해 fallback으로 선언한 컴포넌트를 렌더할 수 있다.

이 방식은 사용하지 않아서 페이지 전환 시 로딩 페이지 자체를 사용했지만 Suspense를 사용했더라면 전체적인 UI는 그대로 보여지고 변화되는 곳만 지연시켜 사용자에게 보다 좋은 UI를 제공할 수 있었을 것 같다.

어떻게 써봤니

'use client'
import { modelNum } from '@/app/recoil/admin'
import dynamic from 'next/dynamic'
import { useEffect, useState } from 'react'
import { useRecoilState } from 'recoil'
import ModelUsage from '../model/ModelUsage'

const ModelContainer = () => {
  const [titleNum, setTitleNum] = useRecoilState(modelNum)
  const [modelData, setModelData] = useState<ResponseModelData | null>(null)
  const marginBorder =
    titleNum === 1 ? 'ml-[154px]' : titleNum === 2 ? 'ml-[290px]' : ''

  const ModelTrain = dynamic(() => import('../model/ModelTrain'))
  const ModelManage = dynamic(() => import('../model/ModelManage'))

  useEffect(() => {
    const fetchData = async () => {
      const response = await fetch(
        `${process.env.NEXT_PUBLIC_NEXT_SERVER}/api/admin/model/service`,
      )
      const resData = await response.json()
      setModelData(resData.result)
    }
    fetchData()
  }, [])

  return (
    <div className="flex flex-col bg-white w-[full] pl-[54px] pt-[27px] pb-[44px]">
      <div className="text-[28px] font-bold mb-7">AI 관리</div>
      <div className="w-[1021px] h-0 border border-[#616161] mb-7"></div>
      <div className="flex w-[1013px]">
        {titleNum === 0 && modelData && <ModelUsage modelData={modelData} />}
        {titleNum === 1 && <ModelTrain />}
        {titleNum === 2 && <ModelManage />}
      </div>
    </div>
  )
}

export default ModelContainer


조금은 복잡하지만 관리자 페이지 중 하나로 AI 모델을 관리하는 페이지에 대한 컨테이너 파일이다.

ModelUsage, ModelTrain, ModelManage 컴포넌트는 각 AI모델 사용량, 훈련정보, 관리에 관한 컴포넌트이고
헤더의 클릭에 따라 변하는 titleNum에 따라 렌더링 된다.

파일 전체에 해당하는 ModelContainer가 사용되는 page가 렌더링 된다면 3개의 모델 관련 컴포넌트를 모두 가져온다면 큰 크기에 의해 초기 렌더링이 지연 되겠지만,  

  const ModelTrain = dynamic(() => import('../model/ModelTrain'))
  const ModelManage = dynamic(() => import('../model/ModelManage'))

다음과 같이 동적 import를 통해 정말 사용 될 때 가져오는 동적 방식을 통해 초기 지연을 방지한다.

위에서 설명한 Suspense와 Loading을 통해 fallback에 해당하는 컴포넌트로 톱니바퀴가 돌아가는 로딩 애니메이션을 넣었다면 굳이 깜빡거리는 것이나 지연없이 훨씬 자연스러운 UI를 제공했을 수 있을 것 같다.

현재 진행하는 프로젝트엔 동적 import와  Suspense 모두 사용해봐야겠다.

728x90

'코딩 > UNCLASSIFIED' 카테고리의 다른 글

깃허브 여러 파일 업로드  (1) 2022.08.09

p