โ† ๋ชจ๋“  ๊ธ€

reactnext.js

Dynamic import in Next.js

Dynamic import๋ฅผ ์ด์šฉํ•˜๋ฉด ๋น„๋™๊ธฐ์ ์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๋ถˆ๋Ÿฌ ์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

2025.02.152 min read

Dynamic import๋ž€

Dynamic import๋ฅผ ์ด์šฉํ•˜๋ฉด ๋น„๋™๊ธฐ์ ์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๋ถˆ๋Ÿฌ ์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

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

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ES2020์—์„œ๋Š” ์†์‰ฝ๊ฒŒ Dynamic import๋ฅผ ์ง€์›ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
์ฝ”๋“œ์—์„œ ์œ ์˜ํ•ด์•ผ ํ•  ์ ์€ async/await์„ ์ด์šฉํ•ด import ๋ฌธ์„ ์ž‘์„ฑํ•˜๊ณ  ์žˆ๋‹ค๋Š” ์ ์ž…๋‹ˆ๋‹ค.

Dynamic import with React

๋ฆฌ์•กํŠธ์—์„œ lazy ํ•จ์ˆ˜์™€ Dynamic import ๋ฌธ๋ฒ•์„ ์ด์šฉํ•ด์„œ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ณ„๋„์˜ ์ฒญํฌํŒŒ์ผ๋กœ ๋ถ„๋ฆฌํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

tsx
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 ํ•จ์ˆ˜๋Š” ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ์—์„œ๋งŒ ์‚ฌ์šฉ ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ์— ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ๋กœ ํ•œ๋ฒˆ ๊ฐ์‹ธ์„œ ์‚ฌ์šฉํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.

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

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

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

Dynamic function

์ด์ฒ˜๋Ÿผ ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ์—์„œ Dynamic import๋ฅผ ์ง์ ‘ ์„ ์–ธ ํ•  ์ˆ˜ ์—†๋‹ค๋Š” ๋ถˆํŽธํ•จ์ด ์žˆ์–ด, Next.js๋Š” dynamic ํ•จ์ˆ˜๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

tsx
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์— ๋นˆ์ž๋ฆฌ๋กœ ํ‘œ์‹œํ•˜๊ณ  ํด๋ผ์ด์–ธํŠธ์—์„œ ์˜จ์ „ํžˆ ๋Œ€์ฒดํ•จ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.