← λͺ©λ‘μœΌλ‘œ
Dynamic import in Next.js

Dynamic importλž€

Dynamic importλ₯Ό μ΄μš©ν•˜λ©΄ λΉ„λ™κΈ°μ μœΌλ‘œ 데이터λ₯Ό 뢈러 올 수 μžˆμŠ΅λ‹ˆλ‹€.

const loader = async () => import('[path]');
loader().then((data) = console.log(data));

μžλ°”μŠ€ν¬λ¦½νŠΈ ES6μ—μ„œλŠ” μ†μ‰½κ²Œ Dynamic importλ₯Ό μ§€μ›ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€.
μ½”λ“œμ—μ„œ μœ μ˜ν•΄μ•Ό ν•  점은 async/await을 μ΄μš©ν•΄ import 문을 μž‘μ„±ν•˜κ³  μžˆλ‹€λŠ” μ μž…λ‹ˆλ‹€.

Dynamic import with React

λ¦¬μ•‘νŠΈμ—μ„œ lazy ν•¨μˆ˜μ™€ Dynamic import 문법을 μ΄μš©ν•΄μ„œ μ»΄ν¬λ„ŒνŠΈλ₯Ό λ³„λ„μ˜ 청크파일둜 λΆ„λ¦¬ν•˜λŠ” 것이 κ°€λŠ₯ν•©λ‹ˆλ‹€.

const LazyComponent = lazy(() => import('./LazyComponent'));

const WrapComponent = () => {
  return(
    <Suspense fallback={<div>Loading...</div>}>
      <LazyComponent />
    </Suspense>
  )
}
Dynamic import ν¬μŠ€νŒ…μ΄λ―€λ‘œ Suspense에 λŒ€ν•΄ λ³„λ„λ‘œ κΈ°μˆ ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

Rendering flow

  1. 초기 λ Œλ”λ§ μ™„λ£Œ
  2. 아직 LazyComponentκ°€ λ‘œλ“œ λ˜μ§€ μ•Šμ•˜μœΌλ―€λ‘œ fallback uiκ°€ ν‘œμΆœλ¨
  3. Dynamic import둜 인해 λ³„λ„μ˜ μ²­ν¬νŒŒμΌμ„ μš”μ²­(http)ν•˜κ³  응닡 λ°›μŒ
  4. 응닡 받은 μ»΄ν¬λ„ŒνŠΈλ₯Ό ν•˜μ΄λ“œλ ˆμ΄μ…˜μ„ μ§„ν–‰ν•˜μ—¬ μ»΄ν¬λ„ŒνŠΈλ₯Ό μ‚¬μš©ν•  μ€€λΉ„ μ™„λ£Œ
  5. λ‘œλ”© λŒ€μ‹  LazyComponentλ₯Ό λ Œλ”λ§ν•¨

Dynamic import with Next.js

Next.jsμ—μ„œλ„ lazy ν•¨μˆ˜μ™€ Susepnseλ₯Ό μ΄μš©ν•΄ Dynamic importλ₯Ό μ‚¬μš© ν•  수 μžˆμŠ΅λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ μ„œλ²„ μ»΄ν¬λ„ŒνŠΈμ—μ„œλŠ” 기쑴의 λ°©μ‹λŒ€λ‘œ 적용이 λΆˆκ°€λŠ₯ν•©λ‹ˆλ‹€.
κ·Έ μ΄μœ λŠ” lazy ν•¨μˆ˜λŠ” ν΄λΌμ΄μ–ΈνŠΈ μ»΄ν¬λ„ŒνŠΈμ—μ„œλ§Œ μ‚¬μš© ν•  수 있기 λ•Œλ¬Έμž…λ‹ˆλ‹€. μ„œλ²„ μ»΄ν¬λ„ŒνŠΈμ— μ‚¬μš©ν•˜κΈ° μœ„ν•΄μ„œλŠ” ν΄λΌμ΄μ–ΈνŠΈ μ»΄ν¬λ„ŒνŠΈλ‘œ ν•œλ²ˆ κ°μ‹Έμ„œ μ‚¬μš©ν•΄μ•Όν•©λ‹ˆλ‹€.

// ClientLazyComponent.tsx
'use client';
const LazyComponent = lazy(() => import('./LazyComponent'));

export const ClientComponent = () => {
  return(
    <Suspense fallback={<div>Loading...</div>}>
      <LazyComponent />
    </Suspense>
  )
}

// ServerComponent.tsx
'use server';
export default function ServerPage() {
  return (
    <div>
      <ClientComponent />
    </div>
  )
}

Dynamic function

이처럼 μ„œλ²„ μ»΄ν¬λ„ŒνŠΈμ—μ„œ Dynamic importλ₯Ό 직접 μ„ μ–Έ ν•  수 μ—†λ‹€λŠ” λΆˆνŽΈν•¨μ΄ μžˆμ–΄, Next.jsλŠ” dynamic ν•¨μˆ˜λ₯Ό μ œκ³΅ν•©λ‹ˆλ‹€.

'use server';

const LazyComponent = dynamic(() => import('[path]'), {
  ssr: true,
  loading: () => <div>Loading...</div>
})

export default function ServerPage() {
  return (
    <LazyComponent />
  )
}

이 ν•¨μˆ˜μ˜ νŠΉμ§•μ€ μ„œλ²„/ν΄λΌμ΄μ–ΈνŠΈ μ»΄ν¬λ„ŒνŠΈμ—μ„œ λͺ¨λ‘ μ‚¬μš© ν•  수 있으며 λ³„λ„μ˜ Suspense μ‘°μ°¨ μ„ μ–Έ ν•  ν•„μš”κ°€ μ—†λ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€.

Lazy vs Dynamic

두가지 λ°©λ²•μœΌλ‘œ Dynamic importκ°€ λͺ¨λ‘ κ°€λŠ₯ν•˜λ‹€λ©΄ μ–΄λ–€ 것을 선택해야 ν• κΉŒμš”?

Dynamic function

  • μ„œλ²„μ™€ ν΄λΌμ΄μ–ΈνŠΈ μ»΄ν¬λ„ŒνŠΈ λͺ¨λ‘μ—μ„œ μ‚¬μš© κ°€λŠ₯
  • ssr μ˜΅μ…˜μ„ 톡해 μ„œλ²„ μ‚¬μ΄λ“œ λ Œλ”λ§ μ—¬λΆ€ μ œμ–΄ κ°€λŠ₯
  • λ³„λ„μ˜ Suspense 없이도 loading UI ν‘œμ‹œ κ°€λŠ₯

Lazy

  • lazy ν•¨μˆ˜λ₯Ό μ΄μš©ν•˜λ©΄ μ–΄λ–€ μ»΄ν¬λ„ŒνŠΈλ₯Ό μ‚¬μš©ν•˜λ“ μ§€ λ³„λ„μ˜ 청크 νŒŒμΌμ„ μš”μ²­ν•˜λŠ” λ°©μ‹μœΌλ‘œ λ™μž‘

κ°€μž₯ 큰 차이점은 SSR을 μ œμ™Έν•  수 μžˆλŠ”μ§€ μ—¬λΆ€μž…λ‹ˆλ‹€. lazy ν•¨μˆ˜λ₯Ό 톡해 'Dynamic importν•˜κ±°λ‚˜, 'Suspense둜 κ°μ‹Έμ„œ λ‘œλ”©μ„ ν‘œμΆœν•œλ‹€κ³  해도 μ΅œμƒμœ„ μ»΄ν¬λ„ŒνŠΈκ°€ μ„œλ²„ μ»΄ν¬λ„ŒνŠΈμΈ 경우 SSR에 ν¬ν•¨λ©λ‹ˆλ‹€.
κ·Έλž˜μ„œ SSR을 μ œμ™Έν•˜κ³  μ‹Άλ‹€λ©΄ dynamic ν•¨μˆ˜λ₯Ό μ΄μš©ν•΄μ•Ό ν•©λ‹ˆλ‹€. SSRμ—μ„œ μ œμ™Έ 함은 초기 HTML에 빈자리둜 ν‘œμ‹œν•˜κ³  ν΄λΌμ΄μ–ΈνŠΈμ—μ„œ μ˜¨μ „νžˆ λŒ€μ²΄ν•¨μ„ μ˜λ―Έν•©λ‹ˆλ‹€.