[Next.js] Dynamic Import

찐새·2022년 6월 19일
0

next.js

목록 보기
24/41
post-thumbnail

Dynamic Import

import한 components나 함수는 보통 코드 상단에 존재한다. 이것의 의미는 유저가 해당 페이지를 실행할 시 코드에 적힌 모든 import 요소를 다운로드한다는 의미이다. 평소에는 다운로드의 순서나 여부가 크게 상관 없지만, 때에 따라 특정 조건에서만 요소를 로드할 필요가 있다.

Next.jsDynamic Import를 통해 선별적으로 components를 로드할 수 있다.

Normal Import

// tokoopne1.tsx
export default function Tokoopne1() {
  console.log("I'm Dynamic");
  return <h1>Dynamic</h1>;
}

이러한 component가 있다고 하자. 로그인 페이지에서 B버튼을 눌렀을 때만 보여주고 싶다면 B버튼 활성화 분기 아래에 해당 component를 삽입하고 import할 것이다.

// enter.tsx
import type { NextPage } from "next";
import Tokoopne1 from "@components/tokoopne1";

const Enter: NextPage = () => {
  return (
    <div>
	  <button>Email</button>
      <button>Phone</button>
    {button === Email ? (
    	<h1>Email Plz</h1>
  	  ) : (
    	<Tokoonpne1 />
      )
    </div>
  );
};

보여지는 것은 아래와 같다.

언뜻 보기에 Phone 버튼을 눌렀을 때만 호출되는 듯 보인다. 하지만 네트워크에서 해당 페이지를 확인해 보면 버튼을 누르기 전에 로드했음을 알 수 있다.

새로고침 후 Phone버튼을 누르기 전임에도 이미 현재 페이지는 Tokoopne1 컴포넌트를 다운받아 놓은 상태다.

Dynamic Import

Dynamic Import는 다음과 같이 사용한다.

// enter.tsx
import type { NextPage } from "next";
import dynamic from "next/dynamic";

const Tokoopne1 = dynamic(() => import("@components/tokoopne1"));

const Enter: NextPage = () => {
  return (
    <div>
	  <button>Email</button>
      <button>Phone</button>
    {button === Email ? (
    	<h1>Email Plz</h1>
  	  ) : (
    	<Tokoonpne1 />
      )
    </div>
  );
};

겉으로 보기에는 Dynamic Import 역시 큰 차이가 없어 보인다. 하지만 네트워크를 확인하면 전혀 다르다.

Normal Import의 네크워크 이미지와 비교해보면, Tokoopne1가 검색은 되지만 import가 된 상태는 아니다. 즉, 해당 버튼을 누르기 전에는 유저의 브라우저에 다운로드하지 않는다.

Phone 버튼을 눌러야 해당 컴포넌트가 다운로드된다.

dynamic()은 사전 로드가 작동하도록 모듈의 최상위에 표시되어야 하기 때문에 렌더링 내부에서는 사용할 수 없다.

또한 SSR과 함께 작동하므로 dynamic(() => import("@components/tokoopne1"), { ssr: false })과 같이 서버 사이드 렌더링 여부를 설정할 수 있다.

Lazy-load Import

유저의 네트워크 속도가 느리거나 component의 크기가 매우매우 커서 로드가 빠르게 되지 않으면 유저는 빈 화면을 보고 있어야 한다. 그런 상황을 방지하기 위해 loading component를 추가할 수 있다.

const Tokoopne1 = dynamic(
  () =>
    new Promise((resolve) =>
      setTimeout(() => resolve(import("@components/tokoopne1")), 10000)
    ),
  {
    ssr: false,
    loading: () => <span>Loading a big Component</span>
  }
);

인위적으로 10초 후에 컴포넌트를 불러오는 코드이다. loading 프로퍼티는 해당 component가 로드될 때까지 보여줄 화면을 구성한다. 또다른 방법으로는 suspense를 사용하는 것이다.

// enter.tsx
import type { NextPage } from "next";
import dynamic from "next/dynamic";

const Tokoopne1 = dynamic(
  () =>
    new Promise((resolve) =>
      setTimeout(() => resolve(import("@components/tokoopne1")), 10000)
    ),
  {
    ssr: false,
    suspense: true,
  }
);

const Enter: NextPage = () => {
  return (
    <div>
	  <button>Email</button>
      <button>Phone</button>
    {button === Email ? (
    	<h1>Email Plz</h1>
  	  ) : (
    	<Suspense fallback="Loading a big component">
          <Tokoopne1 />
       	</Suspense>
      )
    </div>
  );
};

Next.js에서 제공하는 <Suspense>를 이용하면 컴포넌트 형식으로 로딩 화면을 구성할 수 있다.


참고
노마드 코더 - 캐럿마켓 클론코딩
Next.js Docs - dynamic-import#with-custom-loading-component

profile
프론트엔드 개발자가 되고 싶다

0개의 댓글